@labdigital/commercetools-mock 2.61.0 → 2.61.2
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/dist/index.mjs +14 -10
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -4
- package/src/repositories/business-unit.ts +2 -5
- package/src/repositories/customer/actions.ts +2 -5
- package/src/repositories/helpers.test.ts +25 -0
- package/src/repositories/helpers.ts +5 -0
- package/src/services/cart.test.ts +5 -1
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":["uuidv4","values: string[]","headersInit: HeadersInit","result: Record<string, string>","uuidv4","token: Token","uuidv4","options: { enabled: boolean; validate: boolean }","_storage: AbstractStorage","uuidv4","a","taxedItemPrices: TaxedItemPrice[]","taxedShippingPrice: TaxedItemPrice | undefined","taxPortions: TaxPortion[]","netAmount: number","grossAmount: number","taxAmount: number","result: Record<number, ShippingRatePriceTier>","totalGross: CentPrecisionMoney","Decimal","totalNet: CentPrecisionMoney","taxPortions: TaxPortion[]","taxedPrice: TaxedItemPrice","taxCategory: TaxCategory | undefined","uuidv4","product: Product | null","variant: ProductVariant | undefined","uuidv4","lineItem: Writable<LineItem> | undefined","customLineItem","custom: CustomFields | undefined","storedBusinessUnit: BusinessUnit | undefined","resource: Writable<Cart>","product: Product | null","uuidv4","resolved: ReturnInfo","syncData: SyncInfo","resource: Writable<Order>","product: Product","variant: ProductVariant | undefined","cartLikeForMatching: Writable<Cart>","stateReference: StateReference | undefined","resource: QuoteRequest","resource: AssociateRole","resource: AttributeGroup","resource: CartDiscount","result: ExpandResult","uuidv4","resource: Category","uuidv4","node: Category","ancestors: CategoryReference[]","resource: Channel","resource: CustomObject","addresses: Address[]","addresses","storesForCustomer: StoreKeyReference[]","resource: Customer","updatedResource: Customer","stores: Store[]","resource: CustomerGroup","resource: DiscountCode","resource: DiscountGroup","resource: Extension","resource: InventoryEntry","resource: OrderEdit","uuidv4","updatedTransaction: Transaction","resource: Payment","_storage: AbstractStorage","ratingsDistribution: { [key: string]: number }","Token","e","fn: NudFunction<T> | undefined","generateMatchFunc","getLexer","parsed: any","expressions: RangeExpression[] | FilterExpression[] | TypeSymbol[]","expr: any","ranges: any","func: (obj: any) => boolean","isSearchAndExpression","isSearchOrExpression","isSearchNotExpression","isSearchFilterExpression","isSearchRangeExpression","isSearchExactExpression","isSearchExistsExpression","isSearchFullTextExpression","isSearchFullTextPrefixExpression","isSearchPrefixExpression","isSearchWildCardExpression","generateMatchFunc","variants: Writable<ProductVariant>[]","results: ProductSearchResult[]","uuidv4","priceToAdd","variantDraft: ProductVariantDraft","variant","existingAttr","price","taxCategoryReference: TaxCategoryReference | undefined","productStateReference: StateReference | undefined","productType: ProductTypeReference | undefined","categoryReferences: CategoryReference[]","taxCategoryReference: TaxCategoryReference | undefined","productStateReference: StateReference | undefined","productData: ProductData","resource: Product","resource: ProductDiscount","expr: any","value","result: FacetResults","result: Writable<TermFacetResult>","terms: Record<any, number>","values: number[]","variableMap: Record<string, QueryParam>","resource: ProductSelection","resource: ProductType","result: AttributeDefinition[]","stateReference: StateReference | undefined","stateReference: StateReference | undefined","resource: RecurrencePolicy","resource: RecurringOrder","resource: Review","resource: ShippingMethod","z","product: Product | null","varId: number | undefined","uuidv4","lineItem: Writable<ShoppingListLineItem> | undefined","resource: ShoppingList","lineItem: Writable<ShoppingListLineItem>","resource: StandalonePrice","resource: State","resource: Store","resource: Subscription","uuidv4","resource: TaxCategory","result: FieldDefinition[]","resource: Type","resource: Zone","err: any","params: QueryParams","cartOrOrder: Cart | Order | null","cartDraft: CartDraft","draft: CustomObjectDraft","result: CustomerSignInResult","searchParams: ProductProjectionQueryParams","DEFAULT_OPTIONS: CommercetoolsMockOptions","_globalListeners: SetupServer[]","config: Config"],"sources":["../src/constants.ts","../src/exceptions.ts","../src/helpers.ts","../src/lib/proxy.ts","../src/lib/password.ts","../src/oauth/helpers.ts","../src/oauth/store.ts","../src/oauth/server.ts","../src/projectAPI.ts","../src/repositories/errors.ts","../src/repositories/abstract.ts","../src/repositories/product-tailoring.ts","../src/repositories/helpers.ts","../src/lib/tax.ts","../src/shipping.ts","../src/repositories/cart/helpers.ts","../src/repositories/cart/actions.ts","../src/repositories/cart/index.ts","../src/repositories/order/actions.ts","../src/repositories/order/index.ts","../src/repositories/quote-request/actions.ts","../src/repositories/quote-request/index.ts","../src/repositories/as-associate.ts","../src/repositories/associate-role.ts","../src/repositories/attribute-group.ts","../src/repositories/business-unit.ts","../src/repositories/cart-discount/actions.ts","../src/repositories/cart-discount/index.ts","../src/lib/expandParser.ts","../src/repositories/category/actions.ts","../src/repositories/category/index.ts","../src/repositories/channel.ts","../src/repositories/custom-object.ts","../src/repositories/customer/actions.ts","../src/repositories/customer/index.ts","../src/repositories/customer-group.ts","../src/repositories/discount-code/actions.ts","../src/repositories/discount-code/index.ts","../src/repositories/discount-group/actions.ts","../src/repositories/discount-group/index.ts","../src/lib/masking.ts","../src/repositories/extension.ts","../src/repositories/inventory-entry/actions.ts","../src/repositories/inventory-entry/index.ts","../src/repositories/my-customer.ts","../src/repositories/my-order.ts","../src/repositories/order-edit.ts","../src/repositories/payment/helpers.ts","../src/repositories/payment/actions.ts","../src/repositories/payment/index.ts","../src/lib/review-statistics.ts","../vendor/perplex/lexer-state.ts","../vendor/perplex/token.ts","../vendor/perplex/token-types.ts","../vendor/perplex/lexer.ts","../vendor/pratt/index.ts","../src/lib/projectionSearchFilter.ts","../src/lib/productSearchFilter.ts","../src/lib/searchQueryTypeChecker.ts","../src/priceSelector.ts","../src/product-search.ts","../src/repositories/product/helpers.ts","../src/repositories/product/actions.ts","../src/repositories/product/index.ts","../src/repositories/product-discount.ts","../src/lib/haversine.ts","../src/lib/predicateParser.ts","../src/product-projection-search.ts","../src/repositories/product-projection.ts","../src/repositories/product-selection.ts","../src/repositories/product-type.ts","../src/repositories/project.ts","../src/repositories/quote/actions.ts","../src/repositories/quote/index.ts","../src/repositories/quote-staged/actions.ts","../src/repositories/quote-staged/index.ts","../src/repositories/recurrence-policy/actions.ts","../src/repositories/recurrence-policy/index.ts","../src/repositories/recurring-order/actions.ts","../src/repositories/recurring-order/index.ts","../src/repositories/review.ts","../src/repositories/shipping-method/helpers.ts","../src/repositories/shipping-method/actions.ts","../src/repositories/shipping-method/index.ts","../src/repositories/shopping-list/actions.ts","../src/repositories/shopping-list/index.ts","../src/repositories/standalone-price.ts","../src/repositories/state.ts","../src/repositories/store.ts","../src/repositories/subscription.ts","../src/repositories/tax-category/helpers.ts","../src/repositories/tax-category/actions.ts","../src/repositories/tax-category/index.ts","../src/repositories/type/actions.ts","../src/repositories/type/index.ts","../src/repositories/zone.ts","../src/repositories/index.ts","../src/schemas/update-request.ts","../src/validate.ts","../src/services/abstract.ts","../src/services/as-associate-cart.ts","../src/services/as-associate-order.ts","../src/services/as-associate-quote-request.ts","../src/services/as-associate.ts","../src/services/associate-roles.ts","../src/services/attribute-group.ts","../src/services/business-units.ts","../src/services/cart.ts","../src/services/cart-discount.ts","../src/services/category.ts","../src/services/channel.ts","../src/services/custom-object.ts","../src/services/customer.ts","../src/services/customer-group.ts","../src/services/discount-code.ts","../src/services/discount-group.ts","../src/services/extension.ts","../src/services/inventory-entry.ts","../src/services/my-business-unit.ts","../src/services/my-cart.ts","../src/services/my-customer.ts","../src/services/my-order.ts","../src/services/my-payment.ts","../src/services/my-shopping-list.ts","../src/services/order.ts","../src/services/payment.ts","../src/services/product.ts","../src/services/product-discount.ts","../src/services/product-projection.ts","../src/services/product-selection.ts","../src/services/product-type.ts","../src/services/quote.ts","../src/services/quote-request.ts","../src/services/quote-staged.ts","../src/services/recurrence-policy.ts","../src/services/recurring-order.ts","../src/services/reviews.ts","../src/services/shipping-method.ts","../src/services/shopping-list.ts","../src/services/standalone-price.ts","../src/services/state.ts","../src/services/store.ts","../src/services/subscription.ts","../src/services/tax-category.ts","../src/services/type.ts","../src/services/zone.ts","../src/services/index.ts","../src/services/project.ts","../src/storage/abstract.ts","../src/storage/in-memory.ts","../src/ctMock.ts"],"sourcesContent":["export const DEFAULT_API_HOSTNAME = \"https://api.*.commercetools.com\";\nexport const DEFAULT_AUTH_HOSTNAME = \"https://auth.*.commercetools.com\";\n","export abstract class BaseError {\n\tabstract message: string;\n\n\tabstract errors?: BaseError[];\n}\n\nexport class CommercetoolsError<T extends BaseError> extends Error {\n\tinfo: T;\n\n\tstatusCode: number;\n\n\terrors: BaseError[];\n\n\tconstructor(info: T, statusCode = 400) {\n\t\tsuper(info.message);\n\t\tthis.info = info;\n\t\tthis.statusCode = statusCode || 500;\n\t\tthis.errors = info.errors ?? [];\n\t}\n}\n\nexport interface InvalidRequestError {\n\treadonly code: \"invalid_request\";\n\treadonly message: string;\n}\n\nexport interface AuthError {\n\treadonly statusCode: number;\n\treadonly message: string;\n\treadonly error: string;\n\treadonly error_description: string;\n}\n","import type { OutgoingHttpHeaders } from \"node:http\";\nimport type { ParsedQs } from \"qs\";\nimport { v4 as uuidv4 } from \"uuid\";\n\nexport const getBaseResourceProperties = () => ({\n\tid: uuidv4(),\n\tcreatedAt: new Date().toISOString(),\n\tlastModifiedAt: new Date().toISOString(),\n\tversion: 0,\n});\n\n/**\n * Do a nested lookup by using a path. For example `foo.bar.value` will\n * return obj['foo']['bar']['value']\n */\nexport const nestedLookup = (obj: any, path: string): any => {\n\tif (!path || path === \"\") {\n\t\treturn obj;\n\t}\n\n\tconst parts = path.split(\".\");\n\tlet val = obj;\n\n\tfor (let i = 0; i < parts.length; i++) {\n\t\tconst part = parts[i];\n\t\tif (val === undefined) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tval = val[part];\n\t}\n\n\treturn val;\n};\n\nexport const queryParamsArray = (\n\tinput: string | ParsedQs | string[] | ParsedQs[] | undefined,\n): string[] | undefined => {\n\tif (input === undefined) {\n\t\treturn undefined;\n\t}\n\n\tconst values: string[] = Array.isArray(input)\n\t\t? (input as string[])\n\t\t: ([input] as string[]);\n\tif (values.length < 1) {\n\t\treturn undefined;\n\t}\n\treturn values;\n};\n\nexport const queryParamsValue = (\n\tvalue: string | ParsedQs | string[] | ParsedQs[] | undefined,\n): string | undefined => {\n\tconst values = queryParamsArray(value);\n\tif (values && values.length > 0) {\n\t\treturn values[0];\n\t}\n\treturn undefined;\n};\n\nexport const cloneObject = <T>(o: T): T => JSON.parse(JSON.stringify(o));\n\nexport const mapHeaderType = (\n\toutgoingHttpHeaders: OutgoingHttpHeaders,\n): HeadersInit => {\n\tconst headersInit: HeadersInit = {};\n\tfor (const key in outgoingHttpHeaders) {\n\t\tconst value = outgoingHttpHeaders[key];\n\t\tif (Array.isArray(value)) {\n\t\t\t// Join multiple values for the same header with a comma\n\t\t\theadersInit[key] = value.join(\", \");\n\t\t} else if (value !== undefined) {\n\t\t\t// Single value or undefined\n\t\t\theadersInit[key] = value.toString();\n\t\t}\n\t}\n\treturn headersInit;\n};\n\nexport const generateRandomString = (length: number) => {\n\tconst characters =\n\t\t\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\";\n\tlet result = \"\";\n\tfor (let i = 0; i < length; i++) {\n\t\tconst randomIndex = Math.floor(Math.random() * characters.length);\n\t\tresult += characters[randomIndex];\n\t}\n\treturn result;\n};\n","export const copyHeaders = (headers: Headers) => {\n\tconst validHeaders = [\"accept\", \"host\", \"authorization\", \"content-type\"];\n\tconst result: Record<string, string> = {};\n\n\tfor (const [key, value] of headers.entries()) {\n\t\tif (validHeaders.includes(key.toLowerCase())) {\n\t\t\tresult[key] = value;\n\t\t}\n\t}\n\n\treturn result;\n};\n","import type { Customer } from \"@commercetools/platform-sdk\";\nimport { v4 as uuidv4 } from \"uuid\";\n\nconst PWRESET_SECRET = \"pwreset\";\nconst EMAIL_VERIFY_SECRET = \"emailverifysecret\";\n\nexport const validatePassword = (\n\tclearPassword: string,\n\thashedPassword: string,\n) => hashPassword(clearPassword) === hashedPassword;\n\nexport const hashPassword = (clearPassword: string) =>\n\tBuffer.from(clearPassword).toString(\"base64\");\n\nexport const createPasswordResetToken = (customer: Customer, expiresAt: Date) =>\n\tBuffer.from(\n\t\t`${customer.id}:${PWRESET_SECRET}:${expiresAt.getTime()}`,\n\t).toString(\"base64\");\n\nexport const createEmailVerifyToken = (customer: Customer) =>\n\tBuffer.from(`${customer.id}:${EMAIL_VERIFY_SECRET}:${uuidv4()}`).toString(\n\t\t\"base64\",\n\t);\n\nexport const validatePasswordResetToken = (token: string) => {\n\tconst items = Buffer.from(token, \"base64\").toString(\"utf-8\").split(\":\");\n\tconst [customerId, secret, time] = items;\n\n\tif (secret !== PWRESET_SECRET) {\n\t\treturn undefined;\n\t}\n\n\t// Check if the token is expired\n\tif (Number.parseInt(time, 10) < Date.now()) {\n\t\treturn undefined;\n\t}\n\n\treturn customerId;\n};\n\nexport const validateEmailVerifyToken = (token: string) => {\n\tconst items = Buffer.from(token, \"base64\").toString(\"utf-8\").split(\":\");\n\tconst [customerId, secret] = items;\n\tif (secret !== EMAIL_VERIFY_SECRET) {\n\t\treturn undefined;\n\t}\n\n\treturn customerId;\n};\n","import type { Request } from \"express\";\n\nexport const getBearerToken = (request: Request): string | undefined => {\n\tconst authHeader = request.header(\"Authorization\");\n\tconst match = authHeader?.match(/^Bearer\\s(?<token>[^\\s]+)$/);\n\tif (match) {\n\t\treturn match.groups?.token;\n\t}\n\treturn undefined;\n};\n","import { randomBytes } from \"node:crypto\";\nimport { v4 as uuidv4 } from \"uuid\";\n\ntype Token = {\n\taccess_token: string;\n\ttoken_type: \"Bearer\";\n\texpires_in: number;\n\tscope: string;\n\trefresh_token?: string;\n};\n\nexport class OAuth2Store {\n\ttokens: Token[] = [];\n\n\tvalidate = true;\n\n\tconstructor(validate = true) {\n\t\tthis.validate = validate;\n\t}\n\n\taddToken(token: Token) {\n\t\tthis.tokens.push(token);\n\t}\n\n\tgetClientToken(clientId: string, clientSecret: string, scope?: string) {\n\t\tconst token: Token = {\n\t\t\taccess_token: randomBytes(16).toString(\"base64\"),\n\t\t\ttoken_type: \"Bearer\",\n\t\t\texpires_in: 172800,\n\t\t\tscope: scope || \"todo\",\n\t\t\trefresh_token: `my-project-${randomBytes(16).toString(\"base64\")}`,\n\t\t};\n\t\tthis.addToken(token);\n\t\treturn token;\n\t}\n\n\tgetAnonymousToken(\n\t\tprojectKey: string,\n\t\tanonymousId: string | undefined,\n\t\tscope: string,\n\t) {\n\t\tif (!anonymousId) {\n\t\t\tanonymousId = uuidv4();\n\t\t}\n\t\tconst token: Token = {\n\t\t\taccess_token: randomBytes(16).toString(\"base64\"),\n\t\t\ttoken_type: \"Bearer\",\n\t\t\texpires_in: 172800,\n\t\t\tscope: scope\n\t\t\t\t? `${scope} anonymous_id:${anonymousId}`\n\t\t\t\t: `anonymous_id:${anonymousId}`,\n\t\t\trefresh_token: `${projectKey}:${randomBytes(16).toString(\"base64\")}`,\n\t\t};\n\t\tthis.addToken(token);\n\t\treturn token;\n\t}\n\n\tgetCustomerToken(projectKey: string, customerId: string, scope: string) {\n\t\tconst token: Token = {\n\t\t\taccess_token: randomBytes(16).toString(\"base64\"),\n\t\t\ttoken_type: \"Bearer\",\n\t\t\texpires_in: 172800,\n\t\t\tscope: scope\n\t\t\t\t? `${scope} customer_id:${customerId}`\n\t\t\t\t: `customer_id:${customerId}`,\n\t\t\trefresh_token: `${projectKey}:${randomBytes(16).toString(\"base64\")}`,\n\t\t};\n\t\tthis.addToken(token);\n\t\treturn token;\n\t}\n\n\trefreshToken(clientId: string, clientSecret: string, refreshToken: string) {\n\t\tconst existing = this.tokens.find((t) => t.refresh_token === refreshToken);\n\t\tif (!existing) {\n\t\t\treturn undefined;\n\t\t}\n\t\tconst token: Token = {\n\t\t\t...existing,\n\t\t\taccess_token: randomBytes(16).toString(\"base64\"),\n\t\t};\n\t\tthis.addToken(token);\n\n\t\t// We don't want to return the refresh_token again\n\t\treturn {\n\t\t\taccess_token: token.access_token,\n\t\t\ttoken_type: token.token_type,\n\t\t\texpires_in: token.expires_in,\n\t\t\tscope: token.scope,\n\t\t};\n\t}\n\n\tvalidateToken(token: string) {\n\t\tif (!this.validate) return true;\n\n\t\tconst foundToken = this.tokens.find((t) => t.access_token === token);\n\t\tif (foundToken) {\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n}\n","import type { InvalidTokenError } from \"@commercetools/platform-sdk\";\nimport auth from \"basic-auth\";\nimport bodyParser from \"body-parser\";\nimport express, {\n\ttype NextFunction,\n\ttype Request,\n\ttype Response,\n} from \"express\";\nimport type { AuthError, InvalidRequestError } from \"#src/exceptions.ts\";\nimport { CommercetoolsError } from \"#src/exceptions.ts\";\nimport { hashPassword } from \"../lib/password.ts\";\nimport type { CustomerRepository } from \"../repositories/customer/index.ts\";\nimport type { InvalidClientError, UnsupportedGrantType } from \"./errors.ts\";\nimport { getBearerToken } from \"./helpers.ts\";\nimport { OAuth2Store } from \"./store.ts\";\n\ntype AuthRequest = Request & {\n\tcredentials?: {\n\t\tclientId: string;\n\t\tclientSecret: string;\n\t};\n};\nexport type Token = {\n\taccess_token: string;\n\ttoken_type: \"Bearer\";\n\texpires_in: number;\n\tscope: string;\n\trefresh_token?: string;\n};\n\nexport class OAuth2Server {\n\tstore: OAuth2Store;\n\n\tprivate customerRepository: CustomerRepository;\n\n\tconstructor(private options: { enabled: boolean; validate: boolean }) {\n\t\tthis.store = new OAuth2Store(options.validate);\n\t}\n\n\tsetCustomerRepository(repository: CustomerRepository) {\n\t\tthis.customerRepository = repository;\n\t}\n\n\tcreateRouter() {\n\t\tconst router = express.Router();\n\t\trouter.use(bodyParser.urlencoded({ extended: true }));\n\t\trouter.use(this.validateClientCredentials.bind(this));\n\t\trouter.post(\"/token\", this.tokenHandler.bind(this));\n\t\trouter.post(\n\t\t\t\"/:projectKey/customers/token\",\n\t\t\tthis.customerTokenHandler.bind(this),\n\t\t);\n\t\trouter.post(\n\t\t\t\"/:projectKey/in-store/key=:storeKey/customers/token\",\n\t\t\tthis.inStoreCustomerTokenHandler.bind(this),\n\t\t);\n\t\trouter.post(\n\t\t\t\"/:projectKey/anonymous/token\",\n\t\t\tthis.anonymousTokenHandler.bind(this),\n\t\t);\n\t\treturn router;\n\t}\n\n\tcreateMiddleware() {\n\t\tif (!this.options.validate) {\n\t\t\treturn async (\n\t\t\t\trequest: Request,\n\t\t\t\tresponse: Response,\n\t\t\t\tnext: NextFunction,\n\t\t\t) => {\n\t\t\t\tnext();\n\t\t\t};\n\t\t}\n\n\t\treturn async (request: Request, response: Response, next: NextFunction) => {\n\t\t\tconst token = getBearerToken(request);\n\t\t\tif (!token) {\n\t\t\t\treturn next(\n\t\t\t\t\tnew CommercetoolsError<InvalidTokenError>(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcode: \"invalid_token\",\n\t\t\t\t\t\t\tmessage:\n\t\t\t\t\t\t\t\t\"This endpoint requires an access token. You can get one from the authorization server.\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\t401,\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tif (!token || !this.store.validateToken(token)) {\n\t\t\t\treturn next(\n\t\t\t\t\tnew CommercetoolsError<InvalidTokenError>(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcode: \"invalid_token\",\n\t\t\t\t\t\t\tmessage: \"invalid_token\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\t401,\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}\n\n\t\t\treturn next();\n\t\t};\n\t}\n\n\tasync validateClientCredentials(\n\t\trequest: AuthRequest,\n\t\tresponse: Response,\n\t\tnext: NextFunction,\n\t) {\n\t\tconst authHeader = request.header(\"Authorization\");\n\t\tif (!authHeader) {\n\t\t\treturn next(\n\t\t\t\tnew CommercetoolsError<InvalidClientError>(\n\t\t\t\t\t{\n\t\t\t\t\t\tcode: \"invalid_client\",\n\t\t\t\t\t\tmessage:\n\t\t\t\t\t\t\t\"Please provide valid client credentials using HTTP Basic Authentication.\",\n\t\t\t\t\t},\n\t\t\t\t\t401,\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\t\tconst credentials = auth.parse(authHeader);\n\t\tif (!credentials) {\n\t\t\treturn next(\n\t\t\t\tnew CommercetoolsError<InvalidClientError>(\n\t\t\t\t\t{\n\t\t\t\t\t\tcode: \"invalid_client\",\n\t\t\t\t\t\tmessage:\n\t\t\t\t\t\t\t\"Please provide valid client credentials using HTTP Basic Authentication.\",\n\t\t\t\t\t},\n\t\t\t\t\t400,\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\n\t\trequest.credentials = {\n\t\t\tclientId: credentials.name,\n\t\t\tclientSecret: credentials.pass,\n\t\t};\n\n\t\tnext();\n\t}\n\n\tasync tokenHandler(\n\t\trequest: AuthRequest,\n\t\tresponse: Response,\n\t\tnext: NextFunction,\n\t) {\n\t\tif (!request.credentials) {\n\t\t\treturn next(\n\t\t\t\tnew CommercetoolsError<InvalidClientError>(\n\t\t\t\t\t{\n\t\t\t\t\t\tcode: \"invalid_client\",\n\t\t\t\t\t\tmessage: \"Client credentials are missing.\",\n\t\t\t\t\t},\n\t\t\t\t\t401,\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\n\t\tconst grantType = request.query.grant_type || request.body?.grant_type;\n\t\tif (!grantType) {\n\t\t\treturn next(\n\t\t\t\tnew CommercetoolsError<InvalidRequestError>(\n\t\t\t\t\t{\n\t\t\t\t\t\tcode: \"invalid_request\",\n\t\t\t\t\t\tmessage: \"Missing required parameter: grant_type.\",\n\t\t\t\t\t},\n\t\t\t\t\t400,\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\n\t\tif (grantType === \"client_credentials\") {\n\t\t\tconst token = this.store.getClientToken(\n\t\t\t\trequest.credentials.clientId,\n\t\t\t\trequest.credentials.clientSecret,\n\t\t\t\trequest.query.scope?.toString(),\n\t\t\t);\n\t\t\tresponse.status(200).send(token);\n\t\t\treturn;\n\t\t}\n\t\tif (grantType === \"refresh_token\") {\n\t\t\tconst refreshToken =\n\t\t\t\trequest.query.refresh_token?.toString() || request.body?.refresh_token;\n\t\t\tif (!refreshToken) {\n\t\t\t\treturn next(\n\t\t\t\t\tnew CommercetoolsError<InvalidRequestError>(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcode: \"invalid_request\",\n\t\t\t\t\t\t\tmessage: \"Missing required parameter: refresh_token.\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\t400,\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst token = this.store.refreshToken(\n\t\t\t\trequest.credentials.clientId,\n\t\t\t\trequest.credentials.clientSecret,\n\t\t\t\trefreshToken,\n\t\t\t);\n\t\t\tif (!token) {\n\t\t\t\treturn next(\n\t\t\t\t\tnew CommercetoolsError<AuthError>(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tstatusCode: 400,\n\t\t\t\t\t\t\tmessage: \"The refresh token was not found. It may have expired.\",\n\t\t\t\t\t\t\terror: \"invalid_grant\",\n\t\t\t\t\t\t\terror_description:\n\t\t\t\t\t\t\t\t\"The refresh token was not found. It may have expired.\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\t400,\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}\n\t\t\tresponse.status(200).send(token);\n\t\t\treturn;\n\t\t}\n\t\treturn next(\n\t\t\tnew CommercetoolsError<UnsupportedGrantType>(\n\t\t\t\t{\n\t\t\t\t\tcode: \"unsupported_grant_type\",\n\t\t\t\t\tmessage: `Invalid parameter: grant_type: Invalid grant type: ${grantType}`,\n\t\t\t\t},\n\t\t\t\t400,\n\t\t\t),\n\t\t);\n\t}\n\n\tasync customerTokenHandler(\n\t\trequest: AuthRequest,\n\t\tresponse: Response,\n\t\tnext: NextFunction,\n\t) {\n\t\tconst projectKey = request.params.projectKey;\n\t\tconst grantType = request.query.grant_type || request.body?.grant_type;\n\t\tif (!grantType) {\n\t\t\treturn next(\n\t\t\t\tnew CommercetoolsError<InvalidRequestError>(\n\t\t\t\t\t{\n\t\t\t\t\t\tcode: \"invalid_request\",\n\t\t\t\t\t\tmessage: \"Missing required parameter: grant_type.\",\n\t\t\t\t\t},\n\t\t\t\t\t400,\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\n\t\tif (grantType === \"password\") {\n\t\t\tconst username = request.query.username || request.body?.username;\n\t\t\tconst password = hashPassword(\n\t\t\t\trequest.query.password || request.body.password,\n\t\t\t);\n\t\t\tconst scope =\n\t\t\t\trequest.query.scope?.toString() || request.body?.scope?.toString();\n\n\t\t\tconst result = this.customerRepository.query(\n\t\t\t\t{ projectKey: request.params.projectKey },\n\t\t\t\t{\n\t\t\t\t\twhere: [`email = \"${username}\"`, `password = \"${password}\"`],\n\t\t\t\t},\n\t\t\t);\n\n\t\t\tif (result.count === 0) {\n\t\t\t\treturn next(\n\t\t\t\t\tnew CommercetoolsError<any>(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcode: \"invalid_customer_account_credentials\",\n\t\t\t\t\t\t\tmessage: \"Customer account with the given credentials not found.\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\t400,\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst customer = result.results[0];\n\t\t\tconst token = this.store.getCustomerToken(projectKey, customer.id, scope);\n\t\t\tresponse.status(200).send(token);\n\t\t}\n\t}\n\n\tasync inStoreCustomerTokenHandler(\n\t\trequest: Request,\n\t\tresponse: Response,\n\t\tnext: NextFunction,\n\t) {\n\t\tconst projectKey = request.params.projectKey;\n\t\tconst storeKey = request.params.storeKey;\n\t\tconst grantType = request.query.grant_type || request.body.grant_type;\n\t\tif (!grantType) {\n\t\t\treturn next(\n\t\t\t\tnew CommercetoolsError<InvalidRequestError>(\n\t\t\t\t\t{\n\t\t\t\t\t\tcode: \"invalid_request\",\n\t\t\t\t\t\tmessage: \"Missing required parameter: grant_type.\",\n\t\t\t\t\t},\n\t\t\t\t\t400,\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\n\t\tif (grantType === \"password\") {\n\t\t\tconst username = request.query.username || request.body.username;\n\t\t\tconst password = hashPassword(\n\t\t\t\trequest.query.password || request.body.password,\n\t\t\t);\n\t\t\tconst scope =\n\t\t\t\trequest.query.scope?.toString() || request.body.scope?.toString();\n\n\t\t\tconst result = this.customerRepository.query(\n\t\t\t\t{ projectKey, storeKey },\n\t\t\t\t{\n\t\t\t\t\twhere: [`email = \"${username}\"`, `password = \"${password}\"`],\n\t\t\t\t},\n\t\t\t);\n\n\t\t\tif (result.count === 0) {\n\t\t\t\treturn next(\n\t\t\t\t\tnew CommercetoolsError<any>(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcode: \"invalid_customer_account_credentials\",\n\t\t\t\t\t\t\tmessage: \"Customer account with the given credentials not found.\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\t400,\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst customer = result.results[0];\n\t\t\tconst token = this.store.getCustomerToken(projectKey, customer.id, scope);\n\t\t\tresponse.status(200).send(token);\n\t\t\treturn;\n\t\t}\n\t}\n\n\tasync anonymousTokenHandler(\n\t\trequest: Request,\n\t\tresponse: Response,\n\t\tnext: NextFunction,\n\t) {\n\t\tconst projectKey = request.params.projectKey;\n\t\tconst grantType = request.query.grant_type || request.body.grant_type;\n\t\tif (!grantType) {\n\t\t\treturn next(\n\t\t\t\tnew CommercetoolsError<InvalidRequestError>(\n\t\t\t\t\t{\n\t\t\t\t\t\tcode: \"invalid_request\",\n\t\t\t\t\t\tmessage: \"Missing required parameter: grant_type.\",\n\t\t\t\t\t},\n\t\t\t\t\t400,\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\n\t\tif (grantType === \"client_credentials\") {\n\t\t\tconst scope =\n\t\t\t\trequest.query.scope?.toString() || request.body?.scope?.toString();\n\n\t\t\tconst anonymous_id = undefined;\n\n\t\t\tconst token = this.store.getAnonymousToken(\n\t\t\t\tprojectKey,\n\t\t\t\tanonymous_id,\n\t\t\t\tscope,\n\t\t\t);\n\t\t\tresponse.status(200).send(token);\n\t\t\treturn;\n\t\t}\n\t}\n}\n","import type { Config } from \"./config.ts\";\nimport { getBaseResourceProperties } from \"./helpers.ts\";\nimport type { GetParams } from \"./repositories/abstract.ts\";\nimport type { RepositoryMap } from \"./repositories/index.ts\";\nimport type { AbstractStorage } from \"./storage/index.ts\";\nimport type { ResourceMap, ResourceType } from \"./types.ts\";\n\nexport class ProjectAPI {\n\tprivate projectKey: string;\n\n\tprivate _storage: AbstractStorage;\n\n\tprivate _repositories: RepositoryMap;\n\n\treadonly config: Config;\n\n\tconstructor(projectKey: string, repositories: RepositoryMap, config: Config) {\n\t\tthis.projectKey = projectKey;\n\t\tthis.config = config;\n\t\tthis._storage = config.storage;\n\t\tthis._repositories = repositories;\n\t}\n\n\tadd<T extends keyof RepositoryMap & keyof ResourceMap>(\n\t\ttypeId: T,\n\t\tresource: ResourceMap[T],\n\t) {\n\t\tprocess.emitWarning(\n\t\t\t\"ctMock.add() is deprecated, create resources via regular create endpoints \" +\n\t\t\t\t\"or if you are really sure, use unsafeAdd() (but be aware of potential state issues)\",\n\t\t\t\"DeprecationWarning\",\n\t\t);\n\t\tthis.unsafeAdd(typeId, resource);\n\t}\n\n\tunsafeAdd<T extends keyof RepositoryMap & keyof ResourceMap>(\n\t\ttypeId: T,\n\t\tresource: ResourceMap[T],\n\t) {\n\t\tconst repository = this._repositories[typeId];\n\t\tif (repository) {\n\t\t\tthis._storage.add(this.projectKey, typeId, {\n\t\t\t\t...getBaseResourceProperties(),\n\t\t\t\t...resource,\n\t\t\t});\n\t\t} else {\n\t\t\tthrow new Error(`Service for ${typeId} not implemented yet`);\n\t\t}\n\t}\n\n\tget<RT extends ResourceType>(\n\t\ttypeId: RT,\n\t\tid: string,\n\t\tparams?: GetParams,\n\t): ResourceMap[RT] {\n\t\treturn this._storage.get(\n\t\t\tthis.projectKey,\n\t\t\ttypeId,\n\t\t\tid,\n\t\t\tparams,\n\t\t) as ResourceMap[RT];\n\t}\n\n\t// TODO: Not sure if we want to expose this...\n\tgetRepository<RT extends keyof RepositoryMap>(typeId: RT): RepositoryMap[RT] {\n\t\tconst repository = this._repositories[typeId];\n\t\tif (repository !== undefined) {\n\t\t\treturn repository as RepositoryMap[RT];\n\t\t}\n\t\tthrow new Error(\"No such repository\");\n\t}\n}\n","import type { ConcurrentModificationError } from \"@commercetools/platform-sdk\";\nimport { CommercetoolsError } from \"#src/exceptions.ts\";\n\nexport const checkConcurrentModification = (\n\tcurrentVersion: number,\n\texpectedVersion: number,\n\tidentifier: string,\n) => {\n\tif (currentVersion === expectedVersion) return;\n\tthrow new CommercetoolsError<ConcurrentModificationError>(\n\t\t{\n\t\t\tmessage: `Object ${identifier} has a different version than expected. Expected: ${expectedVersion} - Actual: ${currentVersion}.`,\n\t\t\tcurrentVersion: currentVersion,\n\t\t\tcode: \"ConcurrentModification\",\n\t\t},\n\t\t409,\n\t);\n};\n","import { isDeepStrictEqual } from \"node:util\";\nimport type {\n\tBaseResource,\n\tInvalidInputError,\n\tProject,\n\tQueryParam,\n\tResourceNotFoundError,\n\tUpdateAction,\n} from \"@commercetools/platform-sdk\";\nimport type { Config } from \"#src/config.ts\";\nimport { CommercetoolsError } from \"#src/exceptions.ts\";\nimport { cloneObject } from \"../helpers.ts\";\nimport type { AbstractStorage } from \"../storage/index.ts\";\nimport type {\n\tResourceMap,\n\tResourceType,\n\tShallowWritable,\n\tWritable,\n} from \"./../types.ts\";\nimport { checkConcurrentModification } from \"./errors.ts\";\n\nexport type QueryParams = {\n\texpand?: string[];\n\twhere?: string[];\n\toffset?: number;\n\tlimit?: number;\n\n\t// Predicate var values. Should always start with `var.`\n\t[key: string]: QueryParam;\n};\n\nexport type GetParams = {\n\texpand?: string[];\n};\n\nexport type RepositoryContext = {\n\tprojectKey: string;\n\tstoreKey?: string;\n};\n\nexport abstract class AbstractRepository<R extends BaseResource | Project> {\n\tprotected _storage: AbstractStorage;\n\n\tprotected config: Config;\n\n\tprotected actions: AbstractUpdateHandler | undefined;\n\n\tconstructor(config: Config) {\n\t\tthis.config = config;\n\t\tthis._storage = config.storage;\n\t}\n\n\tabstract saveNew({ projectKey }: RepositoryContext, resource: R): void;\n\n\tabstract saveUpdate(\n\t\t{ projectKey }: RepositoryContext,\n\t\tversion: number,\n\t\tresource: R,\n\t): void;\n\n\tabstract postProcessResource(context: RepositoryContext, resource: any): any;\n\n\tprocessUpdateActions(\n\t\tcontext: RepositoryContext,\n\t\tresource: R,\n\t\tversion: number,\n\t\tactions: UpdateAction[],\n\t): R {\n\t\tif (!this.actions) {\n\t\t\tthrow new Error(\"No actions defined\");\n\t\t}\n\n\t\tconst updatedResource = this.actions.apply(\n\t\t\tcontext,\n\t\t\tresource,\n\t\t\tversion,\n\t\t\tactions,\n\t\t);\n\n\t\t// If all actions succeeded we write the new version\n\t\t// to the storage.\n\t\tif (resource.version !== updatedResource.version) {\n\t\t\tthis.saveUpdate(context, version, updatedResource);\n\t\t}\n\n\t\tconst result = this.postProcessResource(context, updatedResource);\n\t\tif (!result) {\n\t\t\tthrow new Error(\"invalid post process action\");\n\t\t}\n\t\treturn result;\n\t}\n}\n\nexport abstract class AbstractResourceRepository<\n\tT extends ResourceType,\n> extends AbstractRepository<ResourceMap[T]> {\n\tprotected _typeId: T;\n\n\tconstructor(typeId: T, config: Config) {\n\t\tsuper(config);\n\t\tthis._typeId = typeId;\n\t}\n\n\tabstract create(context: RepositoryContext, draft: any): ResourceMap[T];\n\n\tprotected getTypeId(): T {\n\t\treturn this._typeId;\n\t}\n\n\tdelete(\n\t\tcontext: RepositoryContext,\n\t\tid: string,\n\t\tparams: GetParams = {},\n\t): ResourceMap[T] | null {\n\t\tconst resource = this._storage.delete(\n\t\t\tcontext.projectKey,\n\t\t\tthis.getTypeId(),\n\t\t\tid,\n\t\t\tparams,\n\t\t);\n\t\treturn resource\n\t\t\t? this.postProcessResource(context, resource, params)\n\t\t\t: null;\n\t}\n\n\tget(\n\t\tcontext: RepositoryContext,\n\t\tid: string,\n\t\tparams: GetParams = {},\n\t): ResourceMap[T] | null {\n\t\tconst resource = this._storage.get(\n\t\t\tcontext.projectKey,\n\t\t\tthis.getTypeId(),\n\t\t\tid,\n\t\t\tparams,\n\t\t);\n\t\treturn resource\n\t\t\t? this.postProcessResource(context, resource, params)\n\t\t\t: null;\n\t}\n\n\tgetByKey(\n\t\tcontext: RepositoryContext,\n\t\tkey: string,\n\t\tparams: GetParams = {},\n\t): ResourceMap[T] | null {\n\t\tconst resource = this._storage.getByKey(\n\t\t\tcontext.projectKey,\n\t\t\tthis.getTypeId(),\n\t\t\tkey,\n\t\t\tparams,\n\t\t);\n\t\treturn resource\n\t\t\t? this.postProcessResource(context, resource, params)\n\t\t\t: null;\n\t}\n\n\tpostProcessResource(\n\t\tcontext: RepositoryContext,\n\t\tresource: ResourceMap[T],\n\t\tparams?: GetParams,\n\t): ResourceMap[T] {\n\t\treturn resource;\n\t}\n\n\tquery(context: RepositoryContext, params: QueryParams = {}) {\n\t\tconst result = this._storage.query(context.projectKey, this.getTypeId(), {\n\t\t\t...params,\n\t\t});\n\n\t\tconst data = result.results.map((r) =>\n\t\t\tthis.postProcessResource(context, r as ResourceMap[T], {\n\t\t\t\texpand: params.expand,\n\t\t\t}),\n\t\t);\n\t\treturn {\n\t\t\t...result,\n\t\t\tresults: data,\n\t\t};\n\t}\n\n\tsaveNew(\n\t\tcontext: RepositoryContext,\n\t\tresource: ShallowWritable<ResourceMap[T]>,\n\t): ResourceMap[T] {\n\t\tresource.version = 1;\n\t\treturn this._storage.add(\n\t\t\tcontext.projectKey,\n\t\t\tthis.getTypeId(),\n\t\t\tresource as any,\n\t\t);\n\t}\n\n\tsaveUpdate(\n\t\tcontext: RepositoryContext,\n\t\tversion: number,\n\t\tresource: ShallowWritable<ResourceMap[T]>,\n\t) {\n\t\t// Check if the resource still exists.\n\t\tconst current = this._storage.get(\n\t\t\tcontext.projectKey,\n\t\t\tthis.getTypeId(),\n\t\t\tresource.id,\n\t\t);\n\t\tif (!current) {\n\t\t\tthrow new CommercetoolsError<ResourceNotFoundError>(\n\t\t\t\t{\n\t\t\t\t\tcode: \"ResourceNotFound\",\n\t\t\t\t\tmessage: \"Resource not found while updating\",\n\t\t\t\t},\n\t\t\t\t400,\n\t\t\t);\n\t\t}\n\n\t\tcheckConcurrentModification(current.version, version, resource.id);\n\n\t\tif (current.version === resource.version) {\n\t\t\tthrow new Error(\"Internal error: no changes to save\");\n\t\t}\n\t\tresource.lastModifiedAt = new Date().toISOString();\n\n\t\tthis._storage.add(context.projectKey, this.getTypeId(), resource as any);\n\n\t\treturn resource;\n\t}\n}\n\ntype UpdateActionHandlerMethod<A, T> = (\n\tcontext: RepositoryContext,\n\tresource: Writable<A>,\n\taction: T,\n) => void;\n\nexport type UpdateHandlerInterface<\n\tA extends BaseResource | Project,\n\tT extends UpdateAction,\n> = {\n\t[P in T as P[\"action\"]]: UpdateActionHandlerMethod<A, P>;\n};\n\nexport class AbstractUpdateHandler {\n\tconstructor(protected _storage: AbstractStorage) {\n\t\tif (!_storage) {\n\t\t\tthrow new Error(\"No storage provided\");\n\t\t}\n\t\tthis._storage = _storage;\n\t}\n\n\tapply<R extends BaseResource | Project>(\n\t\tcontext: RepositoryContext,\n\t\tresource: R,\n\t\tversion: number,\n\t\tactions: UpdateAction[],\n\t): R {\n\t\tconst updatedResource = cloneObject(resource) as ShallowWritable<R>;\n\t\tconst identifier = (resource as BaseResource).id\n\t\t\t? (resource as BaseResource).id\n\t\t\t: (resource as Project).key;\n\n\t\tfor (const action of actions) {\n\t\t\t// Validate if this action exists\n\t\t\t// @ts-expect-error\n\t\t\tif (this[action.action] === undefined) {\n\t\t\t\tthrow new CommercetoolsError<InvalidInputError>({\n\t\t\t\t\tcode: \"InvalidInput\",\n\t\t\t\t\tmessage: `Invalid action ${action.action}`,\n\t\t\t\t\terrors: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcode: \"InvalidInput\",\n\t\t\t\t\t\t\tmessage: `Invalid action ${action.action}`,\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t// @ts-expect-error\n\t\t\tconst updateFunc = this[action.action].bind(this);\n\n\t\t\tif (!updateFunc) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`No mock implemented for update action ${action.action}`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst beforeUpdate = cloneObject(resource);\n\t\t\tupdateFunc(context, updatedResource, action);\n\n\t\t\t// Check if the object is updated. We need to increase the version of\n\t\t\t// an object per action which does an actual modification.\n\t\t\t// This isn't the most performant method to do this (the update action\n\t\t\t// should return a flag) but for now the easiest.\n\t\t\tif (!isDeepStrictEqual(beforeUpdate, updatedResource)) {\n\t\t\t\t// We only check the version when there is an actual modification to\n\t\t\t\t// be stored.\n\t\t\t\tcheckConcurrentModification(resource.version, version, identifier);\n\n\t\t\t\tupdatedResource.version += 1;\n\t\t\t}\n\t\t}\n\t\treturn updatedResource;\n\t}\n}\n","import type {\n\tProductTailoring,\n\tProductTailoringUpdateAction,\n} from \"@commercetools/platform-sdk\";\nimport type { Config } from \"#src/config.ts\";\nimport type { RepositoryContext, UpdateHandlerInterface } from \"./abstract.ts\";\nimport {\n\tAbstractResourceRepository,\n\tAbstractUpdateHandler,\n} from \"./abstract.ts\";\n\nexport class ProductTailoringRepository extends AbstractResourceRepository<\"product-tailoring\"> {\n\tconstructor(config: Config) {\n\t\tsuper(\"product-tailoring\", config);\n\t\tthis.actions = new ProductTailoringUpdateHandler(this._storage);\n\t}\n\n\tcreate(context: RepositoryContext, draft: any): ProductTailoring {\n\t\tthrow new Error(\"Create method for product-tailoring not implemented.\");\n\t}\n}\n\nclass ProductTailoringUpdateHandler\n\textends AbstractUpdateHandler\n\timplements\n\t\tPartial<\n\t\t\tUpdateHandlerInterface<ProductTailoring, ProductTailoringUpdateAction>\n\t\t>\n{\n\tsetSlug() {\n\t\tthrow new Error(\"SetSlug method for product-tailoring not implemented.\");\n\t}\n}\n","import type {\n\t_Money,\n\tAddress,\n\tAssociate,\n\tAssociateDraft,\n\tAssociateRoleAssignment,\n\tAssociateRoleAssignmentDraft,\n\tAssociateRoleKeyReference,\n\tAssociateRoleReference,\n\tAssociateRoleResourceIdentifier,\n\tBaseAddress,\n\tBusinessUnitKeyReference,\n\tBusinessUnitReference,\n\tBusinessUnitResourceIdentifier,\n\tCentPrecisionMoney,\n\tCustomFields,\n\tCustomFieldsDraft,\n\tHighPrecisionMoney,\n\tHighPrecisionMoneyDraft,\n\tInvalidJsonInputError,\n\tPrice,\n\tPriceDraft,\n\tReference,\n\tReferencedResourceNotFoundError,\n\tResourceIdentifier,\n\tRoundingMode,\n\tStore,\n\tStoreKeyReference,\n\tStoreReference,\n\tStoreResourceIdentifier,\n\tType,\n} from \"@commercetools/platform-sdk\";\nimport { Decimal } from \"decimal.js/decimal\";\nimport type { Request } from \"express\";\nimport { v4 as uuidv4 } from \"uuid\";\nimport { CommercetoolsError } from \"#src/exceptions.ts\";\nimport type { AbstractStorage } from \"../storage/index.ts\";\nimport type { RepositoryContext } from \"./abstract.ts\";\n\nexport const createAddress = (\n\tbase: BaseAddress | undefined,\n\tprojectKey: string,\n\tstorage: AbstractStorage,\n): Address | undefined => {\n\tif (!base) return undefined;\n\n\tif (!base?.country) {\n\t\tthrow new Error(\"Country is required\");\n\t}\n\n\treturn {\n\t\t...base,\n\t};\n};\n\nexport const createCustomFields = (\n\tdraft: CustomFieldsDraft | undefined,\n\tprojectKey: string,\n\tstorage: AbstractStorage,\n): CustomFields | undefined => {\n\tif (!draft) return undefined;\n\tif (!draft.type) return undefined;\n\tif (!draft.type.typeId) return undefined;\n\tconst typeResource = storage.getByResourceIdentifier(\n\t\tprojectKey,\n\t\tdraft.type,\n\t) as Type;\n\n\tif (!typeResource) {\n\t\tthrow new Error(\n\t\t\t`No type '${draft.type.typeId}' with id=${draft.type.id} or key=${draft.type.key}`,\n\t\t);\n\t}\n\n\treturn {\n\t\ttype: {\n\t\t\ttypeId: draft.type.typeId,\n\t\t\tid: typeResource.id,\n\t\t},\n\t\tfields: draft.fields ?? {},\n\t};\n};\n\nexport const createPrice = (draft: PriceDraft): Price => ({\n\tid: uuidv4(),\n\tvalue: createTypedMoney(draft.value),\n});\n\n/**\n * Rounds a decimal to the nearest whole number using the specified\n * (Commercetools) rounding mode.\n *\n * @see https://docs.commercetools.com/api/projects/carts#roundingmode\n */\nexport const roundDecimal = (decimal: Decimal, roundingMode: RoundingMode) => {\n\tswitch (roundingMode) {\n\t\tcase \"HalfEven\":\n\t\t\treturn decimal.toDecimalPlaces(0, Decimal.ROUND_HALF_EVEN);\n\t\tcase \"HalfUp\":\n\t\t\treturn decimal.toDecimalPlaces(0, Decimal.ROUND_HALF_UP);\n\t\tcase \"HalfDown\":\n\t\t\treturn decimal.toDecimalPlaces(0, Decimal.ROUND_HALF_DOWN);\n\t\tdefault:\n\t\t\tthrow new Error(`Unknown rounding mode: ${roundingMode}`);\n\t}\n};\n\nexport const createCentPrecisionMoney = (value: _Money): CentPrecisionMoney => {\n\t// Taken from https://docs.adyen.com/development-resources/currency-codes\n\tlet fractionDigits = 2;\n\tswitch (value.currencyCode.toUpperCase()) {\n\t\tcase \"BHD\":\n\t\tcase \"IQD\":\n\t\tcase \"JOD\":\n\t\tcase \"KWD\":\n\t\tcase \"LYD\":\n\t\tcase \"OMR\":\n\t\tcase \"TND\":\n\t\t\tfractionDigits = 3;\n\t\t\tbreak;\n\t\tcase \"CVE\":\n\t\tcase \"DJF\":\n\t\tcase \"GNF\":\n\t\tcase \"IDR\":\n\t\tcase \"JPY\":\n\t\tcase \"KMF\":\n\t\tcase \"KRW\":\n\t\tcase \"PYG\":\n\t\tcase \"RWF\":\n\t\tcase \"UGX\":\n\t\tcase \"VND\":\n\t\tcase \"VUV\":\n\t\tcase \"XAF\":\n\t\tcase \"XOF\":\n\t\tcase \"XPF\":\n\t\t\tfractionDigits = 0;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tfractionDigits = 2;\n\t}\n\n\tif ((value as HighPrecisionMoney & HighPrecisionMoneyDraft).preciseAmount) {\n\t\tthrow new Error(\"HighPrecisionMoney not supported\");\n\t}\n\n\treturn {\n\t\ttype: \"centPrecision\",\n\t\t// centAmont is only optional on HighPrecisionMoney, so this should never\n\t\t// fallback to 0\n\t\tcentAmount: value.centAmount ?? 0,\n\t\tcurrencyCode: value.currencyCode,\n\t\tfractionDigits: fractionDigits,\n\t};\n};\n\nexport const createTypedMoney = (value: _Money): CentPrecisionMoney => {\n\tconst result = createCentPrecisionMoney(value);\n\treturn result;\n};\n\nexport const resolveStoreReference = (\n\tref: StoreResourceIdentifier | undefined,\n\tprojectKey: string,\n\tstorage: AbstractStorage,\n): StoreKeyReference | undefined => {\n\tif (!ref) return undefined;\n\tconst resource = storage.getByResourceIdentifier(projectKey, ref);\n\tif (!resource) {\n\t\tthrow new Error(\"No such store\");\n\t}\n\n\tconst store = resource as Store;\n\treturn {\n\t\ttypeId: \"store\",\n\t\tkey: store.key,\n\t};\n};\n\nexport const getReferenceFromResourceIdentifier = <T extends Reference>(\n\tresourceIdentifier: ResourceIdentifier,\n\tprojectKey: string,\n\tstorage: AbstractStorage,\n): T => {\n\tif (!resourceIdentifier.id && !resourceIdentifier.key) {\n\t\tthrow new CommercetoolsError<InvalidJsonInputError>(\n\t\t\t{\n\t\t\t\tcode: \"InvalidJsonInput\",\n\t\t\t\tmessage: `${resourceIdentifier.typeId}: ResourceIdentifier requires an 'id' xor a 'key'`,\n\t\t\t\tdetailedErrorMessage: `ResourceIdentifier requires an 'id' xor a 'key'`,\n\t\t\t},\n\t\t\t400,\n\t\t);\n\t}\n\n\tconst resource = storage.getByResourceIdentifier(\n\t\tprojectKey,\n\t\tresourceIdentifier,\n\t);\n\tif (!resource) {\n\t\tconst errIdentifier = resourceIdentifier.key\n\t\t\t? `key '${resourceIdentifier.key}'`\n\t\t\t: `identifier '${resourceIdentifier.id}'`;\n\n\t\tthrow new CommercetoolsError<ReferencedResourceNotFoundError>(\n\t\t\t{\n\t\t\t\tcode: \"ReferencedResourceNotFound\",\n\t\t\t\ttypeId: resourceIdentifier.typeId,\n\t\t\t\tmessage: `The referenced object of type '${resourceIdentifier.typeId}' with '${errIdentifier}' was not found. It either doesn't exist, or it can't be accessed from this endpoint (e.g., if the endpoint filters by store or customer account).`,\n\t\t\t},\n\t\t\t400,\n\t\t);\n\t}\n\n\treturn {\n\t\ttypeId: resourceIdentifier.typeId,\n\t\tid: resource?.id,\n\t} as unknown as T;\n};\n\nexport const getStoreKeyReference = (\n\tid: StoreResourceIdentifier,\n\tprojectKey: string,\n\tstorage: AbstractStorage,\n): StoreKeyReference => {\n\tif (id.key) {\n\t\treturn {\n\t\t\ttypeId: \"store\",\n\t\t\tkey: id.key,\n\t\t};\n\t}\n\tconst value = getReferenceFromResourceIdentifier<StoreReference>(\n\t\tid,\n\t\tprojectKey,\n\t\tstorage,\n\t);\n\n\tif (!value.obj?.key) {\n\t\tthrow new Error(\"No store found for reference\");\n\t}\n\treturn {\n\t\ttypeId: \"store\",\n\t\tkey: value.obj?.key,\n\t};\n};\n\nexport const getRepositoryContext = (request: Request): RepositoryContext => ({\n\tprojectKey: request.params.projectKey,\n\tstoreKey: request.params.storeKey,\n});\n\nexport const createAssociate = (\n\ta: AssociateDraft,\n\tprojectKey: string,\n\tstorage: AbstractStorage,\n): Associate | undefined => {\n\tif (!a) return undefined;\n\n\tif (!a.associateRoleAssignments) {\n\t\tthrow new Error(\"AssociateRoleAssignments is required\");\n\t}\n\n\treturn {\n\t\tcustomer: getReferenceFromResourceIdentifier(\n\t\t\ta.customer,\n\t\t\tprojectKey,\n\t\t\tstorage,\n\t\t),\n\t\tassociateRoleAssignments: a.associateRoleAssignments?.map(\n\t\t\t(a: AssociateRoleAssignmentDraft): AssociateRoleAssignment => ({\n\t\t\t\tassociateRole: getAssociateRoleKeyReference(\n\t\t\t\t\ta.associateRole,\n\t\t\t\t\tprojectKey,\n\t\t\t\t\tstorage,\n\t\t\t\t),\n\t\t\t\tinheritance: a.inheritance as string,\n\t\t\t}),\n\t\t),\n\t};\n};\n\nexport const getAssociateRoleKeyReference = (\n\tid: AssociateRoleResourceIdentifier,\n\tprojectKey: string,\n\tstorage: AbstractStorage,\n): AssociateRoleKeyReference => {\n\tif (id.key) {\n\t\treturn {\n\t\t\ttypeId: \"associate-role\",\n\t\t\tkey: id.key,\n\t\t};\n\t}\n\n\tconst value = getReferenceFromResourceIdentifier<AssociateRoleReference>(\n\t\tid,\n\t\tprojectKey,\n\t\tstorage,\n\t);\n\n\tif (!value.obj?.key) {\n\t\tthrow new Error(\"No associate-role found for reference\");\n\t}\n\n\treturn {\n\t\ttypeId: \"associate-role\",\n\t\tkey: value.obj?.key,\n\t};\n};\n\nexport const getBusinessUnitKeyReference = (\n\tid: BusinessUnitResourceIdentifier,\n\tprojectKey: string,\n\tstorage: AbstractStorage,\n): BusinessUnitKeyReference => {\n\tif (id.key) {\n\t\treturn {\n\t\t\ttypeId: \"business-unit\",\n\t\t\tkey: id.key,\n\t\t};\n\t}\n\n\tconst value = getReferenceFromResourceIdentifier<BusinessUnitReference>(\n\t\tid,\n\t\tprojectKey,\n\t\tstorage,\n\t);\n\n\tif (!value.obj?.key) {\n\t\tthrow new Error(\"No business-unit found for reference\");\n\t}\n\n\treturn {\n\t\ttypeId: \"business-unit\",\n\t\tkey: value.obj?.key,\n\t};\n};\n","import type {\n\tCart,\n\tTaxCategory,\n\tTaxedItemPrice,\n\tTaxedPrice,\n\tTaxPortion,\n\tTaxRate,\n} from \"@commercetools/platform-sdk\";\nimport { createCentPrecisionMoney } from \"#src/repositories/helpers.ts\";\n\ntype TaxableResource = Pick<\n\tCart,\n\t\"lineItems\" | \"customLineItems\" | \"shippingInfo\" | \"totalPrice\"\n>;\n\nexport const calculateTaxTotals = (\n\tresource: TaxableResource,\n): {\n\ttaxedPrice?: TaxedPrice;\n\ttaxedShippingPrice?: TaxedItemPrice;\n} => {\n\tconst taxedItemPrices: TaxedItemPrice[] = [];\n\n\tresource.lineItems.forEach((item) => {\n\t\tif (item.taxedPrice) {\n\t\t\ttaxedItemPrices.push(item.taxedPrice);\n\t\t}\n\t});\n\n\tresource.customLineItems.forEach((item) => {\n\t\tif (item.taxedPrice) {\n\t\t\ttaxedItemPrices.push(item.taxedPrice);\n\t\t}\n\t});\n\n\tlet taxedShippingPrice: TaxedItemPrice | undefined;\n\tif (resource.shippingInfo?.taxedPrice) {\n\t\ttaxedShippingPrice = resource.shippingInfo.taxedPrice;\n\t\ttaxedItemPrices.push(resource.shippingInfo.taxedPrice);\n\t}\n\n\tif (!taxedItemPrices.length) {\n\t\treturn {\n\t\t\ttaxedPrice: undefined,\n\t\t\ttaxedShippingPrice,\n\t\t};\n\t}\n\n\tconst currencyCode = resource.totalPrice.currencyCode;\n\tconst toMoney = (centAmount: number) =>\n\t\tcreateCentPrecisionMoney({\n\t\t\tcurrencyCode,\n\t\t\tcentAmount,\n\t\t});\n\n\tlet totalNet = 0;\n\tlet totalGross = 0;\n\tlet totalTax = 0;\n\n\tconst taxPortionsByRate = new Map<\n\t\tstring,\n\t\t{ rate: number; name?: string; centAmount: number }\n\t>();\n\n\ttaxedItemPrices.forEach((price) => {\n\t\ttotalNet += price.totalNet.centAmount;\n\t\ttotalGross += price.totalGross.centAmount;\n\t\tconst priceTax = price.totalTax\n\t\t\t? price.totalTax.centAmount\n\t\t\t: price.totalGross.centAmount - price.totalNet.centAmount;\n\t\ttotalTax += Math.max(priceTax, 0);\n\n\t\tprice.taxPortions?.forEach((portion) => {\n\t\t\tconst key = `${portion.rate}-${portion.name ?? \"\"}`;\n\t\t\tconst existing = taxPortionsByRate.get(key) ?? {\n\t\t\t\trate: portion.rate,\n\t\t\t\tname: portion.name,\n\t\t\t\tcentAmount: 0,\n\t\t\t};\n\t\t\texisting.centAmount += portion.amount.centAmount;\n\t\t\ttaxPortionsByRate.set(key, existing);\n\t\t});\n\t});\n\n\tconst taxPortions: TaxPortion[] = Array.from(taxPortionsByRate.values()).map(\n\t\t(portion) => ({\n\t\t\trate: portion.rate,\n\t\t\tname: portion.name,\n\t\t\tamount: toMoney(portion.centAmount),\n\t\t}),\n\t);\n\n\treturn {\n\t\ttaxedPrice: {\n\t\t\ttotalNet: toMoney(totalNet),\n\t\t\ttotalGross: toMoney(totalGross),\n\t\t\ttaxPortions,\n\t\t\ttotalTax: totalTax > 0 ? toMoney(totalTax) : undefined,\n\t\t},\n\t\ttaxedShippingPrice,\n\t};\n};\n\nexport const buildTaxedPriceFromRate = (\n\tamount: number,\n\tcurrencyCode: string,\n\ttaxRate?: TaxRate,\n): TaxedItemPrice | undefined => {\n\tif (!taxRate) {\n\t\treturn undefined;\n\t}\n\n\tconst toMoney = (centAmount: number) =>\n\t\tcreateCentPrecisionMoney({\n\t\t\ttype: \"centPrecision\",\n\t\t\tcurrencyCode,\n\t\t\tcentAmount,\n\t\t});\n\n\tlet netAmount: number;\n\tlet grossAmount: number;\n\tlet taxAmount: number;\n\n\tif (taxRate.includedInPrice) {\n\t\tgrossAmount = amount;\n\t\ttaxAmount = Math.round(\n\t\t\t(grossAmount * taxRate.amount) / (1 + taxRate.amount),\n\t\t);\n\t\tnetAmount = grossAmount - taxAmount;\n\t} else {\n\t\tnetAmount = amount;\n\t\ttaxAmount = Math.round(netAmount * taxRate.amount);\n\t\tgrossAmount = netAmount + taxAmount;\n\t}\n\n\treturn {\n\t\ttotalNet: toMoney(netAmount),\n\t\ttotalGross: toMoney(grossAmount),\n\t\ttotalTax: taxAmount > 0 ? toMoney(taxAmount) : undefined,\n\t\ttaxPortions:\n\t\t\ttaxAmount > 0\n\t\t\t\t? [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\trate: taxRate.amount,\n\t\t\t\t\t\t\tname: taxRate.name,\n\t\t\t\t\t\t\tamount: toMoney(taxAmount),\n\t\t\t\t\t\t},\n\t\t\t\t\t]\n\t\t\t\t: [],\n\t};\n};\n\nexport const calculateTaxedPriceFromRate = (\n\tamount: number,\n\tcurrencyCode: string,\n\ttaxRate?: TaxRate,\n): TaxedItemPrice | undefined =>\n\tbuildTaxedPriceFromRate(amount, currencyCode, taxRate);\n\nexport const calculateTaxedPrice = (\n\tamount: number,\n\ttaxCategory: TaxCategory | undefined,\n\tcurrency: string,\n\tcountry: string | undefined,\n): TaxedPrice | undefined => {\n\tif (!taxCategory || !taxCategory.rates.length) {\n\t\treturn undefined;\n\t}\n\n\tconst taxRate =\n\t\ttaxCategory.rates.find(\n\t\t\t(rate) => !rate.country || rate.country === country,\n\t\t) || taxCategory.rates[0];\n\n\tconst taxedItemPrice = buildTaxedPriceFromRate(amount, currency, taxRate);\n\tif (!taxedItemPrice) {\n\t\treturn undefined;\n\t}\n\n\treturn {\n\t\ttotalNet: taxedItemPrice.totalNet,\n\t\ttotalGross: taxedItemPrice.totalGross,\n\t\ttaxPortions: taxedItemPrice.taxPortions,\n\t\ttotalTax: taxedItemPrice.totalTax,\n\t};\n};\n","import type {\n\tCart,\n\tCartValueTier,\n\tCentPrecisionMoney,\n\tInvalidOperationError,\n\tMissingTaxRateForCountryError,\n\tShippingInfo,\n\tShippingMethod,\n\tShippingRate,\n\tShippingRatePriceTier,\n\tTaxedItemPrice,\n\tTaxPortion,\n} from \"@commercetools/platform-sdk\";\nimport { Decimal } from \"decimal.js\";\nimport { CommercetoolsError } from \"./exceptions.ts\";\nimport type { GetParams, RepositoryContext } from \"./repositories/abstract.ts\";\nimport {\n\tcreateCentPrecisionMoney,\n\troundDecimal,\n} from \"./repositories/helpers.ts\";\nimport type { AbstractStorage } from \"./storage/abstract.ts\";\n\nexport const markMatchingShippingRate = (\n\tcart: Cart,\n\tshippingRate: ShippingRate,\n): ShippingRate => {\n\tconst isMatching =\n\t\tshippingRate.price.currencyCode === cart.totalPrice.currencyCode;\n\treturn {\n\t\t...shippingRate,\n\t\ttiers: markMatchingShippingRatePriceTiers(cart, shippingRate.tiers),\n\t\tisMatching: isMatching,\n\t};\n};\n\nexport const markMatchingShippingRatePriceTiers = (\n\tcart: Cart,\n\ttiers: ShippingRatePriceTier[],\n): ShippingRatePriceTier[] => {\n\tif (tiers.length === 0) {\n\t\treturn [];\n\t}\n\n\tif (new Set(tiers.map((tier) => tier.type)).size > 1) {\n\t\tthrow new Error(\"Can't handle multiple types of tiers\");\n\t}\n\n\tconst tierType = tiers[0].type;\n\tswitch (tierType) {\n\t\tcase \"CartValue\":\n\t\t\treturn markMatchingCartValueTiers(cart, tiers as CartValueTier[]);\n\t\t// case 'CartClassification':\n\t\t// \treturn markMatchingCartClassificationTiers(cart, tiers)\n\t\t// case 'CartScore':\n\t\t// \treturn markMatchingCartScoreTiers(cart, tiers)\n\t\tdefault:\n\t\t\tthrow new Error(`Unsupported tier type: ${tierType}`);\n\t}\n};\n\nconst markMatchingCartValueTiers = (\n\tcart: Cart,\n\ttiers: readonly CartValueTier[],\n): ShippingRatePriceTier[] => {\n\t// Sort tiers from high to low since we only want to match the highest tier\n\tconst sortedTiers = [...tiers].sort(\n\t\t(a, b) => b.minimumCentAmount - a.minimumCentAmount,\n\t);\n\n\t// Find the first tier that matches the cart and set the flag. We push\n\t// the results into a map so that we can output the tiers in the same order as\n\t// we received them.\n\tconst result: Record<number, ShippingRatePriceTier> = {};\n\tlet hasMatchingTier = false;\n\tfor (const tier of sortedTiers) {\n\t\tconst isMatching =\n\t\t\t!hasMatchingTier &&\n\t\t\tcart.totalPrice.currencyCode === tier.price.currencyCode &&\n\t\t\tcart.totalPrice.centAmount >= tier.minimumCentAmount;\n\n\t\tif (isMatching) hasMatchingTier = true;\n\t\tresult[tier.minimumCentAmount] = {\n\t\t\t...tier,\n\t\t\tisMatching: isMatching,\n\t\t};\n\t}\n\n\treturn tiers.map((tier) => result[tier.minimumCentAmount]);\n};\n\n/*\n * Retrieves all the ShippingMethods that can ship to the shipping address of\n * the given Cart. Each ShippingMethod contains exactly one ShippingRate with\n * the flag isMatching set to true. This ShippingRate is used when the\n * ShippingMethod is added to the Cart.\n */\nexport const getShippingMethodsMatchingCart = (\n\tcontext: RepositoryContext,\n\tstorage: AbstractStorage,\n\tcart: Cart,\n\tparams: GetParams = {},\n) => {\n\tif (!cart.shippingAddress?.country) {\n\t\tthrow new CommercetoolsError<InvalidOperationError>({\n\t\t\tcode: \"InvalidOperation\",\n\t\t\tmessage: `The cart with ID '${cart.id}' does not have a shipping address set.`,\n\t\t});\n\t}\n\n\t// Get all shipping methods that have a zone that matches the shipping address\n\tconst zones = storage.query<\"zone\">(context.projectKey, \"zone\", {\n\t\twhere: [`locations(country=\"${cart.shippingAddress.country}\"))`],\n\t\tlimit: 100,\n\t});\n\tconst zoneIds = zones.results.map((zone) => zone.id);\n\tconst shippingMethods = storage.query<\"shipping-method\">(\n\t\tcontext.projectKey,\n\t\t\"shipping-method\",\n\t\t{\n\t\t\twhere: [\n\t\t\t\t\"zoneRates(zone(id in (:zoneIds)))\",\n\t\t\t\t`zoneRates(shippingRates(price(currencyCode=\"${cart.totalPrice.currencyCode}\")))`,\n\t\t\t],\n\t\t\t\"var.zoneIds\": zoneIds,\n\t\t\texpand: params.expand,\n\t\t},\n\t);\n\n\t// Make sure that each shipping method has exactly one shipping rate and\n\t// that the shipping rate is marked as matching\n\tconst results = shippingMethods.results\n\t\t.map((shippingMethod) => {\n\t\t\t// Iterate through the zoneRates, process the shipping rates and filter\n\t\t\t// out all zoneRates which have no matching shipping rates left\n\t\t\tconst rates = shippingMethod.zoneRates\n\t\t\t\t.map((zoneRate) => ({\n\t\t\t\t\tzone: zoneRate.zone,\n\n\t\t\t\t\t// Iterate through the shippingRates and mark the matching ones\n\t\t\t\t\t// then we filter out the non-matching ones\n\t\t\t\t\tshippingRates: zoneRate.shippingRates\n\t\t\t\t\t\t.map((rate) => markMatchingShippingRate(cart, rate))\n\t\t\t\t\t\t.filter((rate) => rate.isMatching),\n\t\t\t\t}))\n\t\t\t\t.filter((zoneRate) => zoneRate.shippingRates.length > 0);\n\n\t\t\treturn {\n\t\t\t\t...shippingMethod,\n\t\t\t\tzoneRates: rates,\n\t\t\t};\n\t\t})\n\t\t.filter((shippingMethod) => shippingMethod.zoneRates.length > 0);\n\n\treturn {\n\t\t...shippingMethods,\n\t\tresults: results,\n\t};\n};\n\n/**\n * Interface for cart-like objects that can be used for shipping calculations\n */\ninterface ShippingCalculationSource {\n\tid: string;\n\ttotalPrice: CentPrecisionMoney;\n\tshippingAddress?: {\n\t\tcountry: string;\n\t\t[key: string]: any;\n\t};\n\ttaxRoundingMode?: string;\n}\n\n/**\n * Creates shipping info from a shipping method, handling all tax calculations and pricing logic.\n */\nexport const createShippingInfoFromMethod = (\n\tcontext: RepositoryContext,\n\tstorage: AbstractStorage,\n\tresource: ShippingCalculationSource,\n\tmethod: ShippingMethod,\n): Omit<ShippingInfo, \"deliveries\"> => {\n\tconst country = resource.shippingAddress!.country;\n\n\t// There should only be one zone rate matching the address, since\n\t// Locations cannot be assigned to more than one zone.\n\t// See https://docs.commercetools.com/api/projects/zones#location\n\tconst zoneRate = method.zoneRates.find((rate) =>\n\t\trate.zone.obj?.locations.some((loc) => loc.country === country),\n\t);\n\n\tif (!zoneRate) {\n\t\t// This shouldn't happen because getShippingMethodsMatchingCart already\n\t\t// filtered out shipping methods without any zones matching the address\n\t\tthrow new Error(\"Zone rate not found\");\n\t}\n\n\t// Shipping rates are defined by currency, and getShippingMethodsMatchingCart\n\t// also matches on currency, so there should only be one in the array.\n\t// See https://docs.commercetools.com/api/projects/shippingMethods#zonerate\n\tconst shippingRate = zoneRate.shippingRates[0];\n\tif (!shippingRate) {\n\t\t// This shouldn't happen because getShippingMethodsMatchingCart already\n\t\t// filtered out shipping methods without any matching rates\n\t\tthrow new Error(\"Shipping rate not found\");\n\t}\n\n\tconst taxCategory = storage.getByResourceIdentifier<\"tax-category\">(\n\t\tcontext.projectKey,\n\t\tmethod.taxCategory,\n\t);\n\n\t// TODO: match state in addition to country\n\tconst taxRate = taxCategory.rates.find((rate) => rate.country === country);\n\n\tif (!taxRate) {\n\t\tthrow new CommercetoolsError<MissingTaxRateForCountryError>({\n\t\t\tcode: \"MissingTaxRateForCountry\",\n\t\t\tmessage: `Tax category '${taxCategory.id}' is missing a tax rate for country '${country}'.`,\n\t\t\ttaxCategoryId: taxCategory.id,\n\t\t});\n\t}\n\n\tconst shippingRateTier = shippingRate.tiers.find((tier) => tier.isMatching);\n\tif (shippingRateTier && shippingRateTier.type !== \"CartValue\") {\n\t\tthrow new Error(\"Non-CartValue shipping rate tier is not supported\");\n\t}\n\n\tlet shippingPrice = shippingRateTier\n\t\t? createCentPrecisionMoney(shippingRateTier.price)\n\t\t: shippingRate.price;\n\n\t// Handle freeAbove: if total is above the freeAbove threshold, shipping is free\n\tif (\n\t\tshippingRate.freeAbove &&\n\t\tshippingRate.freeAbove.currencyCode === resource.totalPrice.currencyCode &&\n\t\tresource.totalPrice.centAmount >= shippingRate.freeAbove.centAmount\n\t) {\n\t\tshippingPrice = {\n\t\t\t...shippingPrice,\n\t\t\tcentAmount: 0,\n\t\t};\n\t}\n\n\t// Calculate tax amounts\n\tconst totalGross: CentPrecisionMoney = taxRate.includedInPrice\n\t\t? shippingPrice\n\t\t: {\n\t\t\t\t...shippingPrice,\n\t\t\t\tcentAmount: roundDecimal(\n\t\t\t\t\tnew Decimal(shippingPrice.centAmount).mul(1 + taxRate.amount),\n\t\t\t\t\tresource.taxRoundingMode || \"HalfEven\",\n\t\t\t\t).toNumber(),\n\t\t\t};\n\n\tconst totalNet: CentPrecisionMoney = taxRate.includedInPrice\n\t\t? {\n\t\t\t\t...shippingPrice,\n\t\t\t\tcentAmount: roundDecimal(\n\t\t\t\t\tnew Decimal(shippingPrice.centAmount).div(1 + taxRate.amount),\n\t\t\t\t\tresource.taxRoundingMode || \"HalfEven\",\n\t\t\t\t).toNumber(),\n\t\t\t}\n\t\t: shippingPrice;\n\n\tconst taxPortions: TaxPortion[] = [\n\t\t{\n\t\t\tname: taxRate.name,\n\t\t\trate: taxRate.amount,\n\t\t\tamount: {\n\t\t\t\t...shippingPrice,\n\t\t\t\tcentAmount: totalGross.centAmount - totalNet.centAmount,\n\t\t\t},\n\t\t},\n\t];\n\n\tconst totalTax: CentPrecisionMoney = {\n\t\t...shippingPrice,\n\t\tcentAmount: taxPortions.reduce(\n\t\t\t(acc, portion) => acc + portion.amount.centAmount,\n\t\t\t0,\n\t\t),\n\t};\n\n\tconst taxedPrice: TaxedItemPrice = {\n\t\ttotalNet,\n\t\ttotalGross,\n\t\ttaxPortions,\n\t\ttotalTax,\n\t};\n\n\treturn {\n\t\tshippingMethod: {\n\t\t\ttypeId: \"shipping-method\" as const,\n\t\t\tid: method.id,\n\t\t},\n\t\tshippingMethodName: method.name,\n\t\tprice: shippingPrice,\n\t\tshippingRate,\n\t\ttaxedPrice,\n\t\ttaxRate,\n\t\ttaxCategory: method.taxCategory,\n\t\tshippingMethodState: \"MatchesCart\",\n\t};\n};\n","import type {\n\tCart,\n\tCustomLineItem,\n\tCustomLineItemDraft,\n\tLineItem,\n\tPrice,\n\tTaxCategory,\n\tTaxCategoryReference,\n} from \"@commercetools/platform-sdk\";\nimport { v4 as uuidv4 } from \"uuid\";\nimport { calculateTaxedPrice } from \"#src/lib/tax.ts\";\nimport type { AbstractStorage } from \"#src/storage/abstract.ts\";\nimport {\n\tcreateCentPrecisionMoney,\n\tcreateCustomFields,\n\tcreateTypedMoney,\n\tgetReferenceFromResourceIdentifier,\n} from \"../helpers.ts\";\n\nexport const selectPrice = ({\n\tprices,\n\tcurrency,\n\tcountry,\n}: {\n\tprices: Price[] | undefined;\n\tcurrency: string;\n\tcountry: string | undefined;\n}): Price | undefined => {\n\tif (!prices) {\n\t\treturn undefined;\n\t}\n\n\t// Quick-and-dirty way of selecting price based on the given currency and country.\n\t// Can be improved later to give more priority to exact matches over\n\t// 'all country' matches, and include customer groups in the mix as well\n\treturn prices.find((price) => {\n\t\tconst countryMatch = !price.country || price.country === country;\n\t\tconst currencyMatch = price.value.currencyCode === currency;\n\t\treturn countryMatch && currencyMatch;\n\t});\n};\n\nexport const calculateLineItemTotalPrice = (lineItem: LineItem): number =>\n\tlineItem.price?.value.centAmount * lineItem.quantity;\n\nexport const calculateCartTotalPrice = (cart: Cart): number => {\n\tconst lineItemsTotal = cart.lineItems.reduce(\n\t\t(cur, item) => cur + item.totalPrice.centAmount,\n\t\t0,\n\t);\n\tconst customLineItemsTotal = cart.customLineItems.reduce(\n\t\t(cur, item) => cur + item.totalPrice.centAmount,\n\t\t0,\n\t);\n\treturn lineItemsTotal + customLineItemsTotal;\n};\n\nexport const createCustomLineItemFromDraft = (\n\tprojectKey: string,\n\tdraft: CustomLineItemDraft,\n\tstorage: AbstractStorage,\n\tcountry?: string,\n): CustomLineItem => {\n\tconst quantity = draft.quantity ?? 1;\n\n\tconst taxCategoryRef = draft.taxCategory\n\t\t? getReferenceFromResourceIdentifier<TaxCategoryReference>(\n\t\t\t\tdraft.taxCategory,\n\t\t\t\tprojectKey,\n\t\t\t\tstorage,\n\t\t\t)\n\t\t: undefined;\n\n\tlet taxCategory: TaxCategory | undefined;\n\tif (taxCategoryRef) {\n\t\ttry {\n\t\t\ttaxCategory =\n\t\t\t\tstorage.get(projectKey, \"tax-category\", taxCategoryRef.id, {}) ||\n\t\t\t\tundefined;\n\t\t} catch (_error) {\n\t\t\t// Tax category not found, continue without tax calculation\n\t\t}\n\t}\n\n\tconst totalPrice = createCentPrecisionMoney({\n\t\t...draft.money,\n\t\tcentAmount: (draft.money.centAmount ?? 0) * quantity,\n\t});\n\n\tconst taxedPrice = taxCategory\n\t\t? calculateTaxedPrice(\n\t\t\t\ttotalPrice.centAmount,\n\t\t\t\ttaxCategory,\n\t\t\t\ttotalPrice.currencyCode,\n\t\t\t\tcountry,\n\t\t\t)\n\t\t: undefined;\n\n\tconst taxRate = taxCategory\n\t\t? taxCategory.rates.find(\n\t\t\t\t(rate) => !rate.country || rate.country === country,\n\t\t\t)\n\t\t: undefined;\n\n\treturn {\n\t\tid: uuidv4(),\n\t\tkey: draft.key,\n\t\tname: draft.name,\n\t\tmoney: createTypedMoney(draft.money),\n\t\tslug: draft.slug,\n\t\tquantity: draft.quantity ?? 1,\n\t\tstate: [],\n\t\ttaxCategory: taxCategoryRef,\n\t\ttaxRate,\n\t\ttaxedPrice,\n\t\tcustom: createCustomFields(draft.custom, projectKey, storage),\n\t\tdiscountedPricePerQuantity: [],\n\t\tperMethodTaxRate: [],\n\t\tpriceMode: draft.priceMode ?? \"Standard\",\n\t\ttotalPrice,\n\t\ttaxedPricePortions: [],\n\t};\n};\n","import type {\n\tAddress,\n\tAddressDraft,\n\tCart,\n\tCartAddCustomLineItemAction,\n\tCartAddItemShippingAddressAction,\n\tCartAddLineItemAction,\n\tCartChangeCustomLineItemMoneyAction,\n\tCartChangeCustomLineItemQuantityAction,\n\tCartChangeLineItemQuantityAction,\n\tCartChangeTaxRoundingModeAction,\n\tCartRemoveCustomLineItemAction,\n\tCartRemoveDiscountCodeAction,\n\tCartRemoveLineItemAction,\n\tCartRemoveShippingMethodAction,\n\tCartSetAnonymousIdAction,\n\tCartSetBillingAddressAction,\n\tCartSetBillingAddressCustomTypeAction,\n\tCartSetCountryAction,\n\tCartSetCustomerEmailAction,\n\tCartSetCustomerIdAction,\n\tCartSetCustomFieldAction,\n\tCartSetCustomShippingMethodAction,\n\tCartSetCustomTypeAction,\n\tCartSetDirectDiscountsAction,\n\tCartSetLineItemCustomFieldAction,\n\tCartSetLineItemCustomTypeAction,\n\tCartSetLineItemPriceAction,\n\tCartSetLineItemShippingDetailsAction,\n\tCartSetLocaleAction,\n\tCartSetShippingAddressAction,\n\tCartSetShippingAddressCustomFieldAction,\n\tCartSetShippingAddressCustomTypeAction,\n\tCartSetShippingMethodAction,\n\tCartUpdateAction,\n\tCustomFields,\n\tGeneralError,\n\tItemShippingDetails,\n\tLineItem,\n\tProduct,\n\tProductPagedQueryResponse,\n\tProductVariant,\n} from \"@commercetools/platform-sdk\";\nimport type {\n\tCustomLineItem,\n\tDirectDiscount,\n} from \"@commercetools/platform-sdk/dist/declarations/src/generated/models/cart\";\nimport type { ShippingMethodResourceIdentifier } from \"@commercetools/platform-sdk/dist/declarations/src/generated/models/shipping-method\";\nimport { v4 as uuidv4 } from \"uuid\";\nimport { CommercetoolsError } from \"#src/exceptions.ts\";\nimport type { Writable } from \"#src/types.ts\";\nimport type { UpdateHandlerInterface } from \"../abstract.ts\";\nimport { AbstractUpdateHandler, type RepositoryContext } from \"../abstract.ts\";\nimport {\n\tcreateAddress,\n\tcreateCentPrecisionMoney,\n\tcreateCustomFields,\n\tcreateTypedMoney,\n} from \"../helpers.ts\";\nimport {\n\tcalculateCartTotalPrice,\n\tcalculateLineItemTotalPrice,\n\tcreateCustomLineItemFromDraft,\n\tselectPrice,\n} from \"./helpers.ts\";\nimport type { CartRepository } from \"./index.ts\";\n\nexport class CartUpdateHandler\n\textends AbstractUpdateHandler\n\timplements Partial<UpdateHandlerInterface<Cart, CartUpdateAction>>\n{\n\tprivate repository: CartRepository;\n\n\tconstructor(storage: any, repository: CartRepository) {\n\t\tsuper(storage);\n\t\tthis.repository = repository;\n\t}\n\taddItemShippingAddress(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Cart>,\n\t\t{ action, address }: CartAddItemShippingAddressAction,\n\t) {\n\t\tconst newAddress = createAddress(\n\t\t\taddress,\n\t\t\tcontext.projectKey,\n\t\t\tthis._storage,\n\t\t);\n\t\tif (newAddress) {\n\t\t\tresource.itemShippingAddresses.push(newAddress);\n\t\t}\n\t}\n\n\taddLineItem(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Cart>,\n\t\t{\n\t\t\tproductId,\n\t\t\tvariantId,\n\t\t\tsku,\n\t\t\tcustom,\n\t\t\tquantity = 1,\n\t\t\taddedAt,\n\t\t\tkey,\n\t\t}: CartAddLineItemAction,\n\t) {\n\t\tlet product: Product | null = null;\n\n\t\tif (productId && variantId) {\n\t\t\t// Fetch product and variant by ID\n\t\t\tproduct = this._storage.get(context.projectKey, \"product\", productId, {});\n\t\t} else if (sku) {\n\t\t\t// Fetch product and variant by SKU\n\t\t\tconst items = this._storage.query(context.projectKey, \"product\", {\n\t\t\t\twhere: [\n\t\t\t\t\t`masterData(current(masterVariant(sku=\"${sku}\"))) or masterData(current(variants(sku=\"${sku}\")))`,\n\t\t\t\t],\n\t\t\t}) as ProductPagedQueryResponse;\n\n\t\t\tif (items.count === 1) {\n\t\t\t\tproduct = items.results[0];\n\t\t\t}\n\t\t}\n\n\t\tif (!product) {\n\t\t\t// Check if product is found\n\t\t\tthrow new CommercetoolsError<GeneralError>({\n\t\t\t\tcode: \"General\",\n\t\t\t\tmessage: sku\n\t\t\t\t\t? `A product containing a variant with SKU '${sku}' not found.`\n\t\t\t\t\t: `A product with ID '${productId}' not found.`,\n\t\t\t});\n\t\t}\n\n\t\t// Find matching variant\n\t\tconst variant: ProductVariant | undefined = [\n\t\t\tproduct.masterData.current.masterVariant,\n\t\t\t...product.masterData.current.variants,\n\t\t].find((x) => {\n\t\t\tif (sku) return x.sku === sku;\n\t\t\tif (variantId) return x.id === variantId;\n\t\t\treturn false;\n\t\t});\n\n\t\tif (!variant) {\n\t\t\t// Check if variant is found\n\t\t\tthrow new CommercetoolsError<GeneralError>({\n\t\t\t\tcode: \"General\",\n\t\t\t\tmessage: sku\n\t\t\t\t\t? `A variant with SKU '${sku}' for product '${product.id}' not found.`\n\t\t\t\t\t: `A variant with ID '${variantId}' for product '${product.id}' not found.`,\n\t\t\t});\n\t\t}\n\n\t\tconst alreadyAdded = resource.lineItems.some(\n\t\t\t(x) => x.productId === product?.id && x.variant.id === variant?.id,\n\t\t);\n\t\tif (alreadyAdded) {\n\t\t\t// increase quantity and update total price\n\t\t\tresource.lineItems.forEach((x) => {\n\t\t\t\tif (x.productId === product?.id && x.variant.id === variant?.id) {\n\t\t\t\t\tx.quantity += quantity;\n\t\t\t\t\tx.totalPrice.centAmount = calculateLineItemTotalPrice(x);\n\t\t\t\t}\n\t\t\t});\n\t\t} else {\n\t\t\t// add line item\n\t\t\tif (!variant.prices?.length) {\n\t\t\t\tthrow new CommercetoolsError<GeneralError>({\n\t\t\t\t\tcode: \"General\",\n\t\t\t\t\tmessage: `A product with ID '${productId}' doesn't have any prices.`,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tconst currency = resource.totalPrice.currencyCode;\n\n\t\t\tconst price = selectPrice({\n\t\t\t\tprices: variant.prices,\n\t\t\t\tcurrency,\n\t\t\t\tcountry: resource.country,\n\t\t\t});\n\t\t\tif (!price) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`No valid price found for ${productId} for country ${resource.country} and currency ${currency}`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tresource.lineItems.push({\n\t\t\t\tid: uuidv4(),\n\t\t\t\tkey,\n\t\t\t\taddedAt: addedAt ? addedAt : new Date().toISOString(),\n\t\t\t\tproductId: product.id,\n\t\t\t\tproductKey: product.key,\n\t\t\t\tproductSlug: product.masterData.current.slug,\n\t\t\t\tproductType: product.productType,\n\t\t\t\tname: product.masterData.current.name,\n\t\t\t\tvariant,\n\t\t\t\tprice: price,\n\t\t\t\ttaxedPricePortions: [],\n\t\t\t\tperMethodTaxRate: [],\n\t\t\t\ttotalPrice: {\n\t\t\t\t\t...price.value,\n\t\t\t\t\ttype: \"centPrecision\",\n\t\t\t\t\tcentAmount: price.value.centAmount * quantity,\n\t\t\t\t},\n\t\t\t\tquantity,\n\t\t\t\tdiscountedPricePerQuantity: [],\n\t\t\t\tlineItemMode: \"Standard\",\n\t\t\t\tpriceMode: \"Platform\",\n\t\t\t\tstate: [],\n\t\t\t\tcustom: createCustomFields(custom, context.projectKey, this._storage),\n\t\t\t});\n\t\t}\n\n\t\t// Update cart total price\n\t\tresource.totalPrice.centAmount = calculateCartTotalPrice(resource);\n\t}\n\n\tchangeLineItemQuantity(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Cart>,\n\t\t{ lineItemId, lineItemKey, quantity }: CartChangeLineItemQuantityAction,\n\t) {\n\t\tlet lineItem: Writable<LineItem> | undefined;\n\n\t\tif (lineItemId) {\n\t\t\tlineItem = resource.lineItems.find((x) => x.id === lineItemId);\n\t\t\tif (!lineItem) {\n\t\t\t\tthrow new CommercetoolsError<GeneralError>({\n\t\t\t\t\tcode: \"General\",\n\t\t\t\t\tmessage: `A line item with ID '${lineItemId}' not found.`,\n\t\t\t\t});\n\t\t\t}\n\t\t} else if (lineItemKey) {\n\t\t\tlineItem = resource.lineItems.find((x) => x.id === lineItemId);\n\t\t\tif (!lineItem) {\n\t\t\t\tthrow new CommercetoolsError<GeneralError>({\n\t\t\t\t\tcode: \"General\",\n\t\t\t\t\tmessage: `A line item with Key '${lineItemKey}' not found.`,\n\t\t\t\t});\n\t\t\t}\n\t\t} else {\n\t\t\tthrow new CommercetoolsError<GeneralError>({\n\t\t\t\tcode: \"General\",\n\t\t\t\tmessage: \"Either lineItemid or lineItemKey needs to be provided.\",\n\t\t\t});\n\t\t}\n\n\t\tif (quantity === 0) {\n\t\t\t// delete line item\n\t\t\tresource.lineItems = resource.lineItems.filter(\n\t\t\t\t(x) => x.id !== lineItemId,\n\t\t\t);\n\t\t} else {\n\t\t\tresource.lineItems.forEach((x) => {\n\t\t\t\tif (x.id === lineItemId && quantity) {\n\t\t\t\t\tx.quantity = quantity;\n\t\t\t\t\tx.totalPrice.centAmount = calculateLineItemTotalPrice(x);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\t// Update cart total price\n\t\tresource.totalPrice.centAmount = calculateCartTotalPrice(resource);\n\t}\n\n\tchangeTaxRoundingMode(\n\t\t_context: RepositoryContext,\n\t\tresource: Writable<Cart>,\n\t\t{ taxRoundingMode }: CartChangeTaxRoundingModeAction,\n\t) {\n\t\tresource.taxRoundingMode = taxRoundingMode;\n\t}\n\n\trecalculate() {\n\t\t// Dummy action when triggering a recalculation of the cart\n\t\t//\n\t\t// From commercetools documentation:\n\t\t// This update action does not set any Cart field in particular,\n\t\t// but it triggers several Cart updates to bring prices and discounts to the latest state.\n\t\t// Those can become stale over time when no Cart updates have been performed for a while\n\t\t// and prices on related Products have changed in the meanwhile.\n\t}\n\n\tremoveDiscountCode(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Cart>,\n\t\t{ discountCode }: CartRemoveDiscountCodeAction,\n\t) {\n\t\tresource.discountCodes = resource.discountCodes.filter(\n\t\t\t(code) => code.discountCode.id !== discountCode.id,\n\t\t);\n\t}\n\n\tremoveLineItem(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Cart>,\n\t\t{ lineItemId, quantity }: CartRemoveLineItemAction,\n\t) {\n\t\tconst lineItem = resource.lineItems.find((x) => x.id === lineItemId);\n\t\tif (!lineItem) {\n\t\t\t// Check if product is found\n\t\t\tthrow new CommercetoolsError<GeneralError>({\n\t\t\t\tcode: \"General\",\n\t\t\t\tmessage: `A line item with ID '${lineItemId}' not found.`,\n\t\t\t});\n\t\t}\n\n\t\tconst shouldDelete = !quantity || quantity >= lineItem.quantity;\n\t\tif (shouldDelete) {\n\t\t\t// delete line item\n\t\t\tresource.lineItems = resource.lineItems.filter(\n\t\t\t\t(x) => x.id !== lineItemId,\n\t\t\t);\n\t\t} else {\n\t\t\t// decrease quantity and update total price\n\t\t\tresource.lineItems.forEach((x) => {\n\t\t\t\tif (x.id === lineItemId && quantity) {\n\t\t\t\t\tx.quantity -= quantity;\n\t\t\t\t\tx.totalPrice.centAmount = calculateLineItemTotalPrice(x);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\t// Update cart total price\n\t\tresource.totalPrice.centAmount = calculateCartTotalPrice(resource);\n\t}\n\n\taddCustomLineItem(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Cart>,\n\t\t{\n\t\t\tmoney,\n\t\t\tname,\n\t\t\tslug,\n\t\t\tquantity = 1,\n\t\t\ttaxCategory,\n\t\t\tcustom,\n\t\t\tpriceMode = \"Standard\",\n\t\t\tkey,\n\t\t}: CartAddCustomLineItemAction,\n\t) {\n\t\tconst customLineItem = createCustomLineItemFromDraft(\n\t\t\tcontext.projectKey,\n\t\t\t{ money, name, slug, quantity, taxCategory, custom, priceMode, key },\n\t\t\tthis._storage,\n\t\t\tresource.shippingAddress?.country ?? resource.country,\n\t\t);\n\n\t\tresource.customLineItems.push(customLineItem);\n\t\tresource.totalPrice.centAmount = calculateCartTotalPrice(resource);\n\t}\n\n\tremoveCustomLineItem(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Cart>,\n\t\t{ customLineItemId, customLineItemKey }: CartRemoveCustomLineItemAction,\n\t) {\n\t\tlet customLineItem;\n\n\t\tif (!customLineItemId && !customLineItemKey) {\n\t\t\tthrow new CommercetoolsError<GeneralError>({\n\t\t\t\tcode: \"General\",\n\t\t\t\tmessage:\n\t\t\t\t\t\"Either customLineItemId or customLineItemKey needs to be provided.\",\n\t\t\t});\n\t\t}\n\n\t\tif (customLineItemId) {\n\t\t\tcustomLineItem = resource.customLineItems.find(\n\t\t\t\t(x) => x.id === customLineItemId,\n\t\t\t);\n\t\t\tif (!customLineItem) {\n\t\t\t\tthrow new CommercetoolsError<GeneralError>({\n\t\t\t\t\tcode: \"General\",\n\t\t\t\t\tmessage: `A custom line item with ID '${customLineItemId}' not found.`,\n\t\t\t\t});\n\t\t\t}\n\t\t\tresource.customLineItems = resource.customLineItems.filter(\n\t\t\t\t(x) => x.id !== customLineItemId,\n\t\t\t);\n\t\t}\n\n\t\tif (customLineItemKey) {\n\t\t\tcustomLineItem = resource.customLineItems.find(\n\t\t\t\t(x) => x.key === customLineItemKey,\n\t\t\t);\n\t\t\tif (!customLineItem) {\n\t\t\t\tthrow new CommercetoolsError<GeneralError>({\n\t\t\t\t\tcode: \"General\",\n\t\t\t\t\tmessage: `A custom line item with key '${customLineItemKey}' not found.`,\n\t\t\t\t});\n\t\t\t}\n\t\t\tresource.customLineItems = resource.customLineItems.filter(\n\t\t\t\t(x) => x.key !== customLineItemKey,\n\t\t\t);\n\t\t}\n\n\t\tresource.totalPrice.centAmount = calculateCartTotalPrice(resource);\n\t}\n\n\tchangeCustomLineItemQuantity(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Cart>,\n\t\t{\n\t\t\tcustomLineItemId,\n\t\t\tcustomLineItemKey,\n\t\t\tquantity,\n\t\t}: CartChangeCustomLineItemQuantityAction,\n\t) {\n\t\tlet customLineItem;\n\n\t\tif (!customLineItemId && !customLineItemKey) {\n\t\t\tthrow new CommercetoolsError<GeneralError>({\n\t\t\t\tcode: \"General\",\n\t\t\t\tmessage:\n\t\t\t\t\t\"Either customLineItemId or customLineItemKey needs to be provided.\",\n\t\t\t});\n\t\t}\n\n\t\tconst setQuantity = (\n\t\t\tcustomLineItem: Writable<CustomLineItem> | undefined,\n\t\t) => {\n\t\t\tif (!customLineItem) {\n\t\t\t\tthrow new CommercetoolsError<GeneralError>({\n\t\t\t\t\tcode: \"General\",\n\t\t\t\t\tmessage: `A custom line item with ${customLineItemId ? `ID '${customLineItemId}'` : `key '${customLineItemKey}'`} not found.`,\n\t\t\t\t});\n\t\t\t}\n\t\t\tcustomLineItem.quantity = quantity;\n\t\t\tcustomLineItem.totalPrice = createCentPrecisionMoney({\n\t\t\t\t...customLineItem.money,\n\t\t\t\tcentAmount: (customLineItem.money.centAmount ?? 0) * quantity,\n\t\t\t});\n\t\t};\n\n\t\tif (customLineItemId) {\n\t\t\tcustomLineItem = resource.customLineItems.find(\n\t\t\t\t(x) => x.id === customLineItemId,\n\t\t\t);\n\t\t\tsetQuantity(customLineItem);\n\t\t}\n\n\t\tif (customLineItemKey) {\n\t\t\tcustomLineItem = resource.customLineItems.find(\n\t\t\t\t(x) => x.key === customLineItemKey,\n\t\t\t);\n\t\t\tsetQuantity(customLineItem);\n\t\t}\n\n\t\t// Update cart total price\n\t\tresource.totalPrice.centAmount = calculateCartTotalPrice(resource);\n\t}\n\n\tchangeCustomLineItemMoney(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Cart>,\n\t\t{\n\t\t\tcustomLineItemId,\n\t\t\tcustomLineItemKey,\n\t\t\tmoney,\n\t\t}: CartChangeCustomLineItemMoneyAction,\n\t) {\n\t\tlet customLineItem;\n\n\t\tconst setMoney = (customLineItem: Writable<CustomLineItem> | undefined) => {\n\t\t\tif (!customLineItem) {\n\t\t\t\tthrow new CommercetoolsError<GeneralError>({\n\t\t\t\t\tcode: \"General\",\n\t\t\t\t\tmessage: `A custom line item with ${customLineItemId ? `ID '${customLineItemId}'` : `key '${customLineItemKey}'`} not found.`,\n\t\t\t\t});\n\t\t\t}\n\t\t\tcustomLineItem.money = createTypedMoney(money);\n\t\t\tcustomLineItem.totalPrice = createCentPrecisionMoney({\n\t\t\t\t...money,\n\t\t\t\tcentAmount: (money.centAmount ?? 0) * customLineItem.quantity,\n\t\t\t});\n\t\t};\n\n\t\tif (customLineItemId) {\n\t\t\tcustomLineItem = resource.customLineItems.find(\n\t\t\t\t(x) => x.id === customLineItemId,\n\t\t\t);\n\t\t\tsetMoney(customLineItem);\n\t\t}\n\n\t\tif (customLineItemKey) {\n\t\t\tcustomLineItem = resource.customLineItems.find(\n\t\t\t\t(x) => x.key === customLineItemKey,\n\t\t\t);\n\t\t\tsetMoney(customLineItem);\n\t\t}\n\n\t\t// Update cart total price\n\t\tresource.totalPrice.centAmount = calculateCartTotalPrice(resource);\n\t}\n\n\tsetAnonymousId(\n\t\t_context: RepositoryContext,\n\t\tresource: Writable<Cart>,\n\t\t{ anonymousId }: CartSetAnonymousIdAction,\n\t) {\n\t\tresource.anonymousId = anonymousId;\n\t\tresource.customerId = undefined;\n\t}\n\n\tsetBillingAddress(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Cart>,\n\t\t{ address }: CartSetBillingAddressAction,\n\t) {\n\t\tresource.billingAddress = createAddress(\n\t\t\taddress,\n\t\t\tcontext.projectKey,\n\t\t\tthis._storage,\n\t\t);\n\t}\n\n\tsetBillingAddressCustomType(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Cart>,\n\t\tcustom: CartSetBillingAddressCustomTypeAction,\n\t) {\n\t\tif (!resource.billingAddress) {\n\t\t\tthrow new Error(\"Resource has no billing address\");\n\t\t}\n\n\t\tif (!custom.type) {\n\t\t\tresource.billingAddress.custom = undefined;\n\t\t\treturn;\n\t\t}\n\n\t\tconst resolvedType = this._storage.getByResourceIdentifier<\"type\">(\n\t\t\tcontext.projectKey,\n\t\t\tcustom.type,\n\t\t);\n\n\t\tif (!resolvedType) {\n\t\t\tthrow new Error(`Type ${custom.type} not found`);\n\t\t}\n\n\t\tresource.billingAddress.custom = {\n\t\t\ttype: {\n\t\t\t\ttypeId: \"type\",\n\t\t\t\tid: resolvedType.id,\n\t\t\t},\n\t\t\tfields: custom.fields || {},\n\t\t};\n\t}\n\n\tsetCountry(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Cart>,\n\t\t{ country }: CartSetCountryAction,\n\t) {\n\t\tresource.country = country;\n\t}\n\n\tsetCustomerEmail(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Cart>,\n\t\t{ email }: CartSetCustomerEmailAction,\n\t) {\n\t\tresource.customerEmail = email;\n\t}\n\n\tsetCustomerId(\n\t\t_context: RepositoryContext,\n\t\tresource: Writable<Cart>,\n\t\t{ customerId }: CartSetCustomerIdAction,\n\t) {\n\t\tresource.anonymousId = undefined;\n\t\tresource.customerId = customerId;\n\t}\n\n\tsetCustomField(\n\t\tcontext: RepositoryContext,\n\t\tresource: Cart,\n\t\t{ name, value }: CartSetCustomFieldAction,\n\t) {\n\t\tif (!resource.custom) {\n\t\t\tthrow new Error(\"Resource has no custom field\");\n\t\t}\n\n\t\tresource.custom.fields[name] = value;\n\t}\n\n\tsetCustomShippingMethod(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Cart>,\n\t\t{\n\t\t\tshippingMethodName,\n\t\t\tshippingRate,\n\t\t\ttaxCategory,\n\t\t\texternalTaxRate,\n\t\t}: CartSetCustomShippingMethodAction,\n\t) {\n\t\tif (externalTaxRate) {\n\t\t\tthrow new Error(\"External tax rate is not supported\");\n\t\t}\n\n\t\tconst tax = taxCategory\n\t\t\t? this._storage.getByResourceIdentifier<\"tax-category\">(\n\t\t\t\t\tcontext.projectKey,\n\t\t\t\t\ttaxCategory,\n\t\t\t\t)\n\t\t\t: undefined;\n\n\t\tresource.shippingInfo = {\n\t\t\tshippingMethodName,\n\t\t\tprice: createCentPrecisionMoney(shippingRate.price),\n\t\t\tshippingRate: {\n\t\t\t\tprice: createTypedMoney(shippingRate.price),\n\t\t\t\ttiers: [],\n\t\t\t},\n\t\t\ttaxCategory: tax\n\t\t\t\t? {\n\t\t\t\t\t\ttypeId: \"tax-category\",\n\t\t\t\t\t\tid: tax?.id,\n\t\t\t\t\t}\n\t\t\t\t: undefined,\n\t\t\tshippingMethodState: \"MatchesCart\",\n\t\t};\n\t}\n\n\tsetCustomType(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Cart>,\n\t\t{ type, fields }: CartSetCustomTypeAction,\n\t) {\n\t\tif (!type) {\n\t\t\tresource.custom = undefined;\n\t\t} else {\n\t\t\tconst resolvedType = this._storage.getByResourceIdentifier(\n\t\t\t\tcontext.projectKey,\n\t\t\t\ttype,\n\t\t\t);\n\t\t\tif (!resolvedType) {\n\t\t\t\tthrow new Error(`Type ${type} not found`);\n\t\t\t}\n\n\t\t\tresource.custom = {\n\t\t\t\ttype: {\n\t\t\t\t\ttypeId: \"type\",\n\t\t\t\t\tid: resolvedType.id,\n\t\t\t\t},\n\t\t\t\tfields: fields || {},\n\t\t\t};\n\t\t}\n\t}\n\n\tsetDirectDiscounts(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Cart>,\n\t\t{ discounts }: CartSetDirectDiscountsAction,\n\t) {\n\t\t// Doesn't apply any discounts logic, just sets the directDiscounts field\n\t\tresource.directDiscounts = discounts.map(\n\t\t\t(discount) =>\n\t\t\t\t({\n\t\t\t\t\t...discount,\n\t\t\t\t\tid: uuidv4(),\n\t\t\t\t}) as DirectDiscount,\n\t\t);\n\t}\n\n\tsetLineItemCustomField(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Cart>,\n\t\t{\n\t\t\tlineItemId,\n\t\t\tlineItemKey,\n\t\t\tname,\n\t\t\tvalue,\n\t\t\taction,\n\t\t}: CartSetLineItemCustomFieldAction,\n\t) {\n\t\tconst lineItem = resource.lineItems.find(\n\t\t\t(x) =>\n\t\t\t\t(lineItemId && x.id === lineItemId) ||\n\t\t\t\t(lineItemKey && x.key === lineItemKey),\n\t\t);\n\n\t\tif (!lineItem) {\n\t\t\t// Check if line item is found\n\t\t\tthrow new CommercetoolsError<GeneralError>({\n\t\t\t\tcode: \"General\",\n\t\t\t\tmessage: lineItemKey\n\t\t\t\t\t? `A line item with key '${lineItemKey}' not found.`\n\t\t\t\t\t: `A line item with ID '${lineItemId}' not found.`,\n\t\t\t});\n\t\t}\n\n\t\tif (!lineItem.custom) {\n\t\t\tthrow new Error(\"Resource has no custom field\");\n\t\t}\n\n\t\tlineItem.custom.fields[name] = value;\n\t}\n\n\tsetLineItemCustomType(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Cart>,\n\t\t{ lineItemId, lineItemKey, type, fields }: CartSetLineItemCustomTypeAction,\n\t) {\n\t\tconst lineItem = resource.lineItems.find(\n\t\t\t(x) =>\n\t\t\t\t(lineItemId && x.id === lineItemId) ||\n\t\t\t\t(lineItemKey && x.key === lineItemKey),\n\t\t);\n\n\t\tif (!lineItem) {\n\t\t\t// Check if line item is found\n\t\t\tthrow new CommercetoolsError<GeneralError>({\n\t\t\t\tcode: \"General\",\n\t\t\t\tmessage: lineItemKey\n\t\t\t\t\t? `A line item with key '${lineItemKey}' not found.`\n\t\t\t\t\t: `A line item with ID '${lineItemId}' not found.`,\n\t\t\t});\n\t\t}\n\n\t\tif (!type) {\n\t\t\tlineItem.custom = undefined;\n\t\t} else {\n\t\t\tconst resolvedType = this._storage.getByResourceIdentifier(\n\t\t\t\tcontext.projectKey,\n\t\t\t\ttype,\n\t\t\t);\n\t\t\tif (!resolvedType) {\n\t\t\t\tthrow new Error(`Type ${type} not found`);\n\t\t\t}\n\n\t\t\tlineItem.custom = {\n\t\t\t\ttype: {\n\t\t\t\t\ttypeId: \"type\",\n\t\t\t\t\tid: resolvedType.id,\n\t\t\t\t},\n\t\t\t\tfields: fields || {},\n\t\t\t};\n\t\t}\n\t}\n\n\tsetLineItemPrice(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Cart>,\n\t\t{ lineItemId, lineItemKey, externalPrice }: CartSetLineItemPriceAction,\n\t) {\n\t\tconst lineItem = resource.lineItems.find(\n\t\t\t(x) =>\n\t\t\t\t(lineItemId && x.id === lineItemId) ||\n\t\t\t\t(lineItemKey && x.key === lineItemKey),\n\t\t);\n\n\t\tif (!lineItem) {\n\t\t\tthrow new CommercetoolsError<GeneralError>({\n\t\t\t\tcode: \"General\",\n\t\t\t\tmessage: lineItemKey\n\t\t\t\t\t? `A line item with key '${lineItemKey}' not found.`\n\t\t\t\t\t: `A line item with ID '${lineItemId}' not found.`,\n\t\t\t});\n\t\t}\n\n\t\tif (!externalPrice && lineItem.priceMode !== \"ExternalPrice\") {\n\t\t\treturn;\n\t\t}\n\n\t\tif (\n\t\t\texternalPrice &&\n\t\t\texternalPrice.currencyCode !== resource.totalPrice.currencyCode\n\t\t) {\n\t\t\tthrow new CommercetoolsError<GeneralError>({\n\t\t\t\tcode: \"General\",\n\t\t\t\tmessage: `Currency mismatch. Expected '${resource.totalPrice.currencyCode}' but got '${externalPrice.currencyCode}'.`,\n\t\t\t});\n\t\t}\n\n\t\tif (externalPrice) {\n\t\t\tlineItem.priceMode = \"ExternalPrice\";\n\t\t\tconst priceValue = createTypedMoney(externalPrice);\n\n\t\t\tlineItem.price = lineItem.price ?? { id: uuidv4() };\n\t\t\tlineItem.price.value = priceValue;\n\t\t} else {\n\t\t\tlineItem.priceMode = \"Platform\";\n\n\t\t\tconst price = selectPrice({\n\t\t\t\tprices: lineItem.variant.prices,\n\t\t\t\tcurrency: resource.totalPrice.currencyCode,\n\t\t\t\tcountry: resource.country,\n\t\t\t});\n\n\t\t\tif (!price) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`No valid price found for ${lineItem.productId} for country ${resource.country} and currency ${resource.totalPrice.currencyCode}`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tlineItem.price = price;\n\t\t}\n\n\t\tconst lineItemTotal = calculateLineItemTotalPrice(lineItem);\n\t\tlineItem.totalPrice = createCentPrecisionMoney({\n\t\t\t...lineItem.price!.value,\n\t\t\tcentAmount: lineItemTotal,\n\t\t});\n\t\tresource.totalPrice.centAmount = calculateCartTotalPrice(resource);\n\t}\n\n\tsetLineItemShippingDetails(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Cart>,\n\t\t{\n\t\t\taction,\n\t\t\tshippingDetails,\n\t\t\tlineItemId,\n\t\t\tlineItemKey,\n\t\t}: CartSetLineItemShippingDetailsAction,\n\t) {\n\t\tconst lineItem = resource.lineItems.find(\n\t\t\t(x) =>\n\t\t\t\t(lineItemId && x.id === lineItemId) ||\n\t\t\t\t(lineItemKey && x.key === lineItemKey),\n\t\t);\n\n\t\tif (!lineItem) {\n\t\t\t// Check if line item is found\n\t\t\tthrow new CommercetoolsError<GeneralError>({\n\t\t\t\tcode: \"General\",\n\t\t\t\tmessage: lineItemKey\n\t\t\t\t\t? `A line item with key '${lineItemKey}' not found.`\n\t\t\t\t\t: `A line item with ID '${lineItemId}' not found.`,\n\t\t\t});\n\t\t}\n\n\t\tlineItem.shippingDetails = {\n\t\t\t...shippingDetails,\n\t\t\tvalid: true,\n\t\t} as ItemShippingDetails;\n\t}\n\n\tsetLocale(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Cart>,\n\t\t{ locale }: CartSetLocaleAction,\n\t) {\n\t\tresource.locale = locale;\n\t}\n\n\tsetShippingAddress(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Cart>,\n\t\t{ address }: CartSetShippingAddressAction,\n\t) {\n\t\tif (!address) {\n\t\t\tresource.shippingAddress = undefined;\n\t\t\treturn;\n\t\t}\n\n\t\tlet custom: CustomFields | undefined;\n\t\tif ((address as Address & AddressDraft).custom) {\n\t\t\tcustom = createCustomFields(\n\t\t\t\t(address as Address & AddressDraft).custom,\n\t\t\t\tcontext.projectKey,\n\t\t\t\tthis._storage,\n\t\t\t);\n\t\t}\n\n\t\tresource.shippingAddress = {\n\t\t\t...address,\n\t\t\tcustom: custom,\n\t\t};\n\t}\n\n\tsetShippingAddressCustomType(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Cart>,\n\t\tcustom: CartSetShippingAddressCustomTypeAction,\n\t) {\n\t\tif (!resource.shippingAddress) {\n\t\t\tthrow new Error(\"Resource has no shipping address\");\n\t\t}\n\n\t\tif (!custom.type) {\n\t\t\tresource.shippingAddress.custom = undefined;\n\t\t\treturn;\n\t\t}\n\n\t\tconst resolvedType = this._storage.getByResourceIdentifier<\"type\">(\n\t\t\tcontext.projectKey,\n\t\t\tcustom.type,\n\t\t);\n\n\t\tif (!resolvedType) {\n\t\t\tthrow new Error(`Type ${custom.type} not found`);\n\t\t}\n\n\t\tresource.shippingAddress.custom = {\n\t\t\ttype: {\n\t\t\t\ttypeId: \"type\",\n\t\t\t\tid: resolvedType.id,\n\t\t\t},\n\t\t\tfields: custom.fields || {},\n\t\t};\n\t}\n\n\tsetShippingMethod(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Cart>,\n\t\t{ shippingMethod }: CartSetShippingMethodAction,\n\t) {\n\t\tif (shippingMethod) {\n\t\t\tresource.shippingInfo = this.repository.createShippingInfo(\n\t\t\t\tcontext,\n\t\t\t\tresource,\n\t\t\t\tshippingMethod,\n\t\t\t);\n\t\t} else {\n\t\t\tresource.shippingInfo = undefined;\n\t\t}\n\t}\n\n\tsetShippingAddressCustomField(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Cart>,\n\t\t{ name, value }: CartSetShippingAddressCustomFieldAction,\n\t) {\n\t\tif (!resource.shippingAddress) {\n\t\t\tthrow new Error(\"Resource has no shipping address\");\n\t\t}\n\t\tif (!resource.shippingAddress.custom) {\n\t\t\tthrow new Error(\"Resource has no custom field\");\n\t\t}\n\t\tresource.shippingAddress.custom.fields[name] = value;\n\t}\n\n\tremoveShippingMethod(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Cart>,\n\t\t{ shippingKey }: CartRemoveShippingMethodAction,\n\t) {\n\t\tif (!resource.shippingInfo) {\n\t\t\treturn;\n\t\t}\n\t\tconst shippingMethod =\n\t\t\tthis._storage.getByResourceIdentifier<\"shipping-method\">(\n\t\t\t\tcontext.projectKey,\n\t\t\t\t{\n\t\t\t\t\ttypeId: \"shipping-method\",\n\t\t\t\t\tkey: shippingKey,\n\t\t\t\t} as ShippingMethodResourceIdentifier,\n\t\t\t);\n\n\t\tif (resource.shippingInfo?.shippingMethod?.id !== shippingMethod.id) {\n\t\t\tthrow new Error(\"Shipping method with key not found\");\n\t\t}\n\n\t\tresource.shippingInfo = undefined;\n\t}\n}\n","import type {\n\tBusinessUnit,\n\tCart,\n\tCartDraft,\n\tGeneralError,\n\tInvalidOperationError,\n\tLineItem,\n\tLineItemDraft,\n\tProduct,\n\tProductPagedQueryResponse,\n\tShippingMethodDoesNotMatchCartError,\n} from \"@commercetools/platform-sdk\";\nimport { v4 as uuidv4 } from \"uuid\";\nimport type { Config } from \"#src/config.ts\";\nimport { CommercetoolsError } from \"#src/exceptions.ts\";\nimport { getBaseResourceProperties } from \"#src/helpers.ts\";\nimport { calculateTaxTotals } from \"#src/lib/tax.ts\";\nimport {\n\tcreateShippingInfoFromMethod,\n\tgetShippingMethodsMatchingCart,\n} from \"#src/shipping.ts\";\nimport type { Writable } from \"#src/types.ts\";\nimport {\n\tAbstractResourceRepository,\n\ttype RepositoryContext,\n} from \"../abstract.ts\";\nimport { createAddress, createCustomFields } from \"../helpers.ts\";\nimport { CartUpdateHandler } from \"./actions.ts\";\nimport {\n\tcalculateCartTotalPrice,\n\tcreateCustomLineItemFromDraft,\n\tselectPrice,\n} from \"./helpers.ts\";\n\nexport class CartRepository extends AbstractResourceRepository<\"cart\"> {\n\tconstructor(config: Config) {\n\t\tsuper(\"cart\", config);\n\t\tthis.actions = new CartUpdateHandler(this._storage, this);\n\t}\n\n\tcreate(context: RepositoryContext, draft: CartDraft): Cart {\n\t\tif (draft.anonymousId && draft.customerId) {\n\t\t\tthrow new CommercetoolsError<InvalidOperationError>({\n\t\t\t\tcode: \"InvalidOperation\",\n\t\t\t\tmessage: \"Can set only one of customer OR anonymousId\",\n\t\t\t});\n\t\t}\n\n\t\t// Validate that the customer exists\n\t\tif (draft.customerId) {\n\t\t\tthis._storage.getByResourceIdentifier(context.projectKey, {\n\t\t\t\ttypeId: \"customer\",\n\t\t\t\tid: draft.customerId,\n\t\t\t});\n\t\t}\n\n\t\tlet storedBusinessUnit: BusinessUnit | undefined;\n\t\tif (draft.businessUnit?.id || draft.businessUnit?.key) {\n\t\t\tstoredBusinessUnit =\n\t\t\t\tthis._storage.getByResourceIdentifier<\"business-unit\">(\n\t\t\t\t\tcontext.projectKey,\n\t\t\t\t\t{\n\t\t\t\t\t\ttypeId: \"business-unit\",\n\t\t\t\t\t\tid: draft.businessUnit.id,\n\t\t\t\t\t\tkey: draft.businessUnit.key,\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t}\n\n\t\tconst lineItems =\n\t\t\tdraft.lineItems?.map((draftLineItem) =>\n\t\t\t\tthis.draftLineItemtoLineItem(\n\t\t\t\t\tcontext.projectKey,\n\t\t\t\t\tdraftLineItem,\n\t\t\t\t\tdraft.currency,\n\t\t\t\t\tdraft.country,\n\t\t\t\t),\n\t\t\t) ?? [];\n\n\t\tconst customLineItems =\n\t\t\tdraft.customLineItems?.map((draftCustomLineItem) =>\n\t\t\t\tcreateCustomLineItemFromDraft(\n\t\t\t\t\tcontext.projectKey,\n\t\t\t\t\tdraftCustomLineItem,\n\t\t\t\t\tthis._storage,\n\t\t\t\t\tdraft.shippingAddress?.country ?? draft.country,\n\t\t\t\t),\n\t\t\t) ?? [];\n\n\t\tconst resource: Writable<Cart> = {\n\t\t\t...getBaseResourceProperties(),\n\t\t\tanonymousId: draft.anonymousId,\n\t\t\tbusinessUnit:\n\t\t\t\tstoredBusinessUnit && draft.businessUnit\n\t\t\t\t\t? {\n\t\t\t\t\t\t\ttypeId: draft.businessUnit.typeId,\n\t\t\t\t\t\t\tkey: storedBusinessUnit.key,\n\t\t\t\t\t\t}\n\t\t\t\t\t: undefined,\n\t\t\tbillingAddress: draft.billingAddress\n\t\t\t\t? createAddress(draft.billingAddress, context.projectKey, this._storage)\n\t\t\t\t: undefined,\n\t\t\tcartState: \"Active\",\n\t\t\tcountry: draft.country,\n\t\t\tcustomerId: draft.customerId,\n\t\t\tcustomerEmail: draft.customerEmail,\n\t\t\tcustomLineItems,\n\t\t\tdirectDiscounts: [],\n\t\t\tdiscountCodes: [],\n\t\t\tinventoryMode: \"None\",\n\t\t\titemShippingAddresses: [],\n\t\t\tlineItems,\n\t\t\tlocale: draft.locale,\n\t\t\tpriceRoundingMode: draft.priceRoundingMode ?? \"HalfEven\",\n\t\t\ttaxCalculationMode: draft.taxCalculationMode ?? \"LineItemLevel\",\n\t\t\ttaxMode: draft.taxMode ?? \"Platform\",\n\t\t\ttaxRoundingMode: draft.taxRoundingMode ?? \"HalfEven\",\n\t\t\ttotalPrice: {\n\t\t\t\ttype: \"centPrecision\",\n\t\t\t\tcentAmount: 0,\n\t\t\t\tcurrencyCode: draft.currency,\n\t\t\t\tfractionDigits: 0,\n\t\t\t},\n\t\t\tshippingMode: \"Single\",\n\t\t\tshippingAddress: draft.shippingAddress\n\t\t\t\t? createAddress(\n\t\t\t\t\t\tdraft.shippingAddress,\n\t\t\t\t\t\tcontext.projectKey,\n\t\t\t\t\t\tthis._storage,\n\t\t\t\t\t)\n\t\t\t\t: undefined,\n\t\t\tshipping: [],\n\t\t\tshippingInfo: undefined,\n\t\t\torigin: draft.origin ?? \"Customer\",\n\t\t\trefusedGifts: [],\n\t\t\tcustom: createCustomFields(\n\t\t\t\tdraft.custom,\n\t\t\t\tcontext.projectKey,\n\t\t\t\tthis._storage,\n\t\t\t),\n\t\t};\n\t\tresource.totalPrice.centAmount = calculateCartTotalPrice(resource);\n\t\tresource.store = context.storeKey\n\t\t\t? { typeId: \"store\", key: context.storeKey }\n\t\t\t: draft.store?.key\n\t\t\t\t? { typeId: \"store\", key: draft.store.key }\n\t\t\t\t: undefined;\n\n\t\t// Set shipping info after resource is created\n\t\tif (draft.shippingMethod) {\n\t\t\tresource.shippingInfo = this.createShippingInfo(\n\t\t\t\tcontext,\n\t\t\t\tresource,\n\t\t\t\tdraft.shippingMethod,\n\t\t\t);\n\t\t}\n\n\t\tconst { taxedPrice, taxedShippingPrice } = calculateTaxTotals(resource);\n\t\tresource.taxedPrice = taxedPrice;\n\t\tresource.taxedShippingPrice = taxedShippingPrice;\n\n\t\treturn this.saveNew(context, resource);\n\t}\n\n\tgetActiveCart(projectKey: string): Cart | undefined {\n\t\t// Get first active cart\n\t\tconst results = this._storage.query(projectKey, this.getTypeId(), {\n\t\t\twhere: [`cartState=\"Active\"`],\n\t\t});\n\t\tif (results.count > 0) {\n\t\t\treturn results.results[0] as Cart;\n\t\t}\n\n\t\treturn;\n\t}\n\n\tdraftLineItemtoLineItem = (\n\t\tprojectKey: string,\n\t\tdraftLineItem: LineItemDraft,\n\t\tcurrency: string,\n\t\tcountry: string | undefined,\n\t): LineItem => {\n\t\tconst { productId, quantity, variantId, sku } = draftLineItem;\n\n\t\tlet product: Product | null = null;\n\n\t\tif (productId && variantId) {\n\t\t\t// Fetch product and variant by ID\n\t\t\tproduct = this._storage.get(projectKey, \"product\", productId, {});\n\t\t} else if (sku) {\n\t\t\t// Fetch product and variant by SKU\n\t\t\tconst items = this._storage.query(projectKey, \"product\", {\n\t\t\t\twhere: [\n\t\t\t\t\t`masterData(current(masterVariant(sku=\"${sku}\"))) or masterData(current(variants(sku=\"${sku}\")))`,\n\t\t\t\t],\n\t\t\t}) as ProductPagedQueryResponse;\n\n\t\t\tif (items.count === 1) {\n\t\t\t\tproduct = items.results[0];\n\t\t\t}\n\t\t}\n\n\t\tif (!product) {\n\t\t\t// Check if product is found\n\t\t\tthrow new CommercetoolsError<GeneralError>({\n\t\t\t\tcode: \"General\",\n\t\t\t\tmessage: sku\n\t\t\t\t\t? `A product containing a variant with SKU '${sku}' not found.`\n\t\t\t\t\t: `A product with ID '${productId}' not found.`,\n\t\t\t});\n\t\t}\n\n\t\t// Find matching variant\n\t\tconst variant = [\n\t\t\tproduct.masterData.current.masterVariant,\n\t\t\t...product.masterData.current.variants,\n\t\t].find((x) => {\n\t\t\tif (sku) return x.sku === sku;\n\t\t\tif (variantId) return x.id === variantId;\n\t\t\treturn false;\n\t\t});\n\n\t\tif (!variant) {\n\t\t\t// Check if variant is found\n\t\t\tthrow new Error(\n\t\t\t\tsku\n\t\t\t\t\t? `A variant with SKU '${sku}' for product '${product.id}' not found.`\n\t\t\t\t\t: `A variant with ID '${variantId}' for product '${product.id}' not found.`,\n\t\t\t);\n\t\t}\n\n\t\tconst quant = quantity ?? 1;\n\n\t\tconst price = selectPrice({ prices: variant.prices, currency, country });\n\t\tif (!price) {\n\t\t\tthrow new Error(\n\t\t\t\t`No valid price found for ${productId} for country ${country} and currency ${currency}`,\n\t\t\t);\n\t\t}\n\n\t\treturn {\n\t\t\tid: uuidv4(),\n\t\t\tproductId: product.id,\n\t\t\tproductKey: product.key,\n\t\t\tproductSlug: product.masterData.current.slug,\n\t\t\tproductType: product.productType,\n\t\t\tname: product.masterData.current.name,\n\t\t\tvariant,\n\t\t\tprice: price,\n\t\t\ttotalPrice: {\n\t\t\t\ttype: \"centPrecision\",\n\t\t\t\tcurrencyCode: price.value.currencyCode,\n\t\t\t\tfractionDigits: price.value.fractionDigits,\n\t\t\t\tcentAmount: price.value.centAmount * quant,\n\t\t\t},\n\t\t\ttaxedPricePortions: [],\n\t\t\tperMethodTaxRate: [],\n\t\t\tquantity: quant,\n\t\t\tdiscountedPricePerQuantity: [],\n\t\t\tlineItemMode: \"Standard\",\n\t\t\tpriceMode: \"Platform\",\n\t\t\tstate: [],\n\t\t\tcustom: createCustomFields(\n\t\t\t\tdraftLineItem.custom,\n\t\t\t\tprojectKey,\n\t\t\t\tthis._storage,\n\t\t\t),\n\t\t};\n\t};\n\n\tcreateShippingInfo(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Cart>,\n\t\tshippingMethodRef: NonNullable<CartDraft[\"shippingMethod\"]>,\n\t): NonNullable<Cart[\"shippingInfo\"]> {\n\t\tif (resource.taxMode === \"External\") {\n\t\t\tthrow new Error(\"External tax rate is not supported\");\n\t\t}\n\n\t\t// Bit of a hack: calling this checks that the resource identifier is\n\t\t// valid (i.e. id xor key) and that the shipping method exists.\n\t\tthis._storage.getByResourceIdentifier<\"shipping-method\">(\n\t\t\tcontext.projectKey,\n\t\t\tshippingMethodRef,\n\t\t);\n\n\t\t// getShippingMethodsMatchingCart does the work of determining whether the\n\t\t// shipping method is allowed for the cart, and which shipping rate to use\n\t\tconst shippingMethods = getShippingMethodsMatchingCart(\n\t\t\tcontext,\n\t\t\tthis._storage,\n\t\t\tresource,\n\t\t\t{\n\t\t\t\texpand: [\"zoneRates[*].zone\"],\n\t\t\t},\n\t\t);\n\n\t\tconst method = shippingMethods.results.find((candidate) =>\n\t\t\tshippingMethodRef.id\n\t\t\t\t? candidate.id === shippingMethodRef.id\n\t\t\t\t: candidate.key === shippingMethodRef.key,\n\t\t);\n\n\t\t// Not finding the method in the results means it's not allowed, since\n\t\t// getShippingMethodsMatchingCart only returns allowed methods and we\n\t\t// already checked that the method exists.\n\t\tif (!method) {\n\t\t\tthrow new CommercetoolsError<ShippingMethodDoesNotMatchCartError>({\n\t\t\t\tcode: \"ShippingMethodDoesNotMatchCart\",\n\t\t\t\tmessage: `The shipping method with ${shippingMethodRef.id ? `ID '${shippingMethodRef.id}'` : `key '${shippingMethodRef.key}'`} is not allowed for the cart with ID '${resource.id}'.`,\n\t\t\t});\n\t\t}\n\n\t\t// Use the shared shipping info creation logic\n\t\treturn createShippingInfoFromMethod(\n\t\t\tcontext,\n\t\t\tthis._storage,\n\t\t\tresource,\n\t\t\tmethod,\n\t\t);\n\t}\n}\n","import type {\n\tCustomLineItemReturnItem,\n\tGeneralError,\n\tLineItemReturnItem,\n\tOrder,\n\tOrderAddPaymentAction,\n\tOrderAddReturnInfoAction,\n\tOrderChangeOrderStateAction,\n\tOrderChangePaymentStateAction,\n\tOrderChangeShipmentStateAction,\n\tOrderSetBillingAddressAction,\n\tOrderSetCustomerEmailAction,\n\tOrderSetCustomerIdAction,\n\tOrderSetCustomFieldAction,\n\tOrderSetCustomTypeAction,\n\tOrderSetDeliveryCustomFieldAction,\n\tOrderSetLineItemCustomFieldAction,\n\tOrderSetLineItemCustomTypeAction,\n\tOrderSetLocaleAction,\n\tOrderSetOrderNumberAction,\n\tOrderSetParcelCustomFieldAction,\n\tOrderSetPurchaseOrderNumberAction,\n\tOrderSetShippingAddressAction,\n\tOrderSetStoreAction,\n\tOrderTransitionStateAction,\n\tOrderUpdateAction,\n\tOrderUpdateSyncInfoAction,\n\tReturnInfo,\n\tState,\n\tStore,\n\tSyncInfo,\n} from \"@commercetools/platform-sdk\";\nimport { CommercetoolsError } from \"#src/exceptions.ts\";\nimport { getBaseResourceProperties } from \"#src/helpers.ts\";\nimport type { Writable } from \"#src/types.ts\";\nimport type { RepositoryContext, UpdateHandlerInterface } from \"../abstract.ts\";\nimport { AbstractUpdateHandler } from \"../abstract.ts\";\nimport { createAddress } from \"../helpers.ts\";\n\nexport class OrderUpdateHandler\n\textends AbstractUpdateHandler\n\timplements Partial<UpdateHandlerInterface<Order, OrderUpdateAction>>\n{\n\taddPayment(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Order>,\n\t\t{ payment }: OrderAddPaymentAction,\n\t) {\n\t\tconst resolvedPayment = this._storage.getByResourceIdentifier(\n\t\t\tcontext.projectKey,\n\t\t\tpayment,\n\t\t);\n\t\tif (!resolvedPayment) {\n\t\t\tthrow new Error(`Payment ${payment.id} not found`);\n\t\t}\n\n\t\tif (!resource.paymentInfo) {\n\t\t\tresource.paymentInfo = {\n\t\t\t\tpayments: [],\n\t\t\t};\n\t\t}\n\n\t\tresource.paymentInfo.payments.push({\n\t\t\ttypeId: \"payment\",\n\t\t\tid: payment.id!,\n\t\t});\n\t}\n\n\taddReturnInfo(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Order>,\n\t\tinfo: OrderAddReturnInfoAction,\n\t) {\n\t\tif (!resource.returnInfo) {\n\t\t\tresource.returnInfo = [];\n\t\t}\n\n\t\tconst resolved: ReturnInfo = {\n\t\t\titems: info.items.map((item) => {\n\t\t\t\tconst common = {\n\t\t\t\t\t...getBaseResourceProperties(),\n\t\t\t\t\tquantity: item.quantity,\n\t\t\t\t\tpaymentState: \"Initial\",\n\t\t\t\t\tshipmentState: \"Initial\",\n\t\t\t\t\tcomment: item.comment,\n\t\t\t\t};\n\t\t\t\tif (item.customLineItemId) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\t...common,\n\t\t\t\t\t\ttype: \"CustomLineItemReturnItem\",\n\t\t\t\t\t\tcustomLineItemId: item.customLineItemId,\n\t\t\t\t\t} as CustomLineItemReturnItem;\n\t\t\t\t}\n\t\t\t\treturn {\n\t\t\t\t\t...common,\n\t\t\t\t\ttype: \"LineItemReturnItem\",\n\t\t\t\t\tlineItemId: item.customLineItemId || item.lineItemId,\n\t\t\t\t} as LineItemReturnItem;\n\t\t\t}),\n\t\t\treturnTrackingId: info.returnTrackingId,\n\t\t\treturnDate: info.returnDate,\n\t\t};\n\n\t\tresource.returnInfo.push(resolved);\n\t}\n\n\tchangeOrderState(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Order>,\n\t\t{ orderState }: OrderChangeOrderStateAction,\n\t) {\n\t\tresource.orderState = orderState;\n\t}\n\n\tchangePaymentState(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Order>,\n\t\t{ paymentState }: OrderChangePaymentStateAction,\n\t) {\n\t\tresource.paymentState = paymentState;\n\t}\n\n\tchangeShipmentState(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Order>,\n\t\t{ shipmentState }: OrderChangeShipmentStateAction,\n\t) {\n\t\tresource.shipmentState = shipmentState;\n\t}\n\n\tsetBillingAddress(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Order>,\n\t\t{ address }: OrderSetBillingAddressAction,\n\t) {\n\t\tresource.billingAddress = createAddress(\n\t\t\taddress,\n\t\t\tcontext.projectKey,\n\t\t\tthis._storage,\n\t\t);\n\t}\n\n\tsetCustomerEmail(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Order>,\n\t\t{ email }: OrderSetCustomerEmailAction,\n\t) {\n\t\tresource.customerEmail = email;\n\t}\n\n\tsetCustomerId(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Order>,\n\t\t{ customerId }: OrderSetCustomerIdAction,\n\t) {\n\t\tresource.customerId = customerId;\n\t}\n\n\tsetCustomField(\n\t\tcontext: RepositoryContext,\n\t\tresource: Order,\n\t\t{ name, value }: OrderSetCustomFieldAction,\n\t) {\n\t\tif (!resource.custom) {\n\t\t\tthrow new Error(\"Resource has no custom field\");\n\t\t}\n\t\tresource.custom.fields[name] = value;\n\t}\n\n\tsetCustomType(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Order>,\n\t\t{ type, fields }: OrderSetCustomTypeAction,\n\t) {\n\t\tif (!type) {\n\t\t\tresource.custom = undefined;\n\t\t} else {\n\t\t\tconst resolvedType = this._storage.getByResourceIdentifier(\n\t\t\t\tcontext.projectKey,\n\t\t\t\ttype,\n\t\t\t);\n\t\t\tif (!resolvedType) {\n\t\t\t\tthrow new Error(`Type ${type} not found`);\n\t\t\t}\n\n\t\t\tresource.custom = {\n\t\t\t\ttype: {\n\t\t\t\t\ttypeId: \"type\",\n\t\t\t\t\tid: resolvedType.id,\n\t\t\t\t},\n\t\t\t\tfields: fields || {},\n\t\t\t};\n\t\t}\n\t}\n\n\tsetDeliveryCustomField(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Order>,\n\t\t{ deliveryId, name, value }: OrderSetDeliveryCustomFieldAction,\n\t) {\n\t\tif (!resource.shippingInfo) {\n\t\t\tthrow new Error(\"Resource has no shipping info\");\n\t\t}\n\n\t\tfor (const delivery of resource.shippingInfo.deliveries || []) {\n\t\t\tif (delivery.id === deliveryId && delivery.custom?.fields) {\n\t\t\t\tdelivery.custom.fields[name] = value;\n\t\t\t}\n\t\t}\n\t}\n\n\tsetLineItemCustomField(\n\t\tcontext: RepositoryContext,\n\t\tresource: Order,\n\t\t{\n\t\t\tlineItemId,\n\t\t\tlineItemKey,\n\t\t\tname,\n\t\t\tvalue,\n\t\t\taction,\n\t\t}: OrderSetLineItemCustomFieldAction,\n\t) {\n\t\tconst lineItem = resource.lineItems.find(\n\t\t\t(x) =>\n\t\t\t\t(lineItemId && x.id === lineItemId) ||\n\t\t\t\t(lineItemKey && x.key === lineItemKey),\n\t\t);\n\n\t\tif (!lineItem) {\n\t\t\t// Check if line item is found\n\t\t\tthrow new CommercetoolsError<GeneralError>({\n\t\t\t\tcode: \"General\",\n\t\t\t\tmessage: lineItemKey\n\t\t\t\t\t? `A line item with key '${lineItemKey}' not found.`\n\t\t\t\t\t: `A line item with ID '${lineItemId}' not found.`,\n\t\t\t});\n\t\t}\n\n\t\tif (!lineItem.custom) {\n\t\t\tthrow new Error(\"Resource has no custom field\");\n\t\t}\n\n\t\tlineItem.custom.fields[name] = value;\n\t}\n\n\tsetLineItemCustomType(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Order>,\n\t\t{ lineItemId, lineItemKey, type, fields }: OrderSetLineItemCustomTypeAction,\n\t) {\n\t\tconst lineItem = resource.lineItems.find(\n\t\t\t(x) =>\n\t\t\t\t(lineItemId && x.id === lineItemId) ||\n\t\t\t\t(lineItemKey && x.key === lineItemKey),\n\t\t);\n\n\t\tif (!lineItem) {\n\t\t\t// Check if line item is found\n\t\t\tthrow new CommercetoolsError<GeneralError>({\n\t\t\t\tcode: \"General\",\n\t\t\t\tmessage: lineItemKey\n\t\t\t\t\t? `A line item with key '${lineItemKey}' not found.`\n\t\t\t\t\t: `A line item with ID '${lineItemId}' not found.`,\n\t\t\t});\n\t\t}\n\n\t\tif (!type) {\n\t\t\tlineItem.custom = undefined;\n\t\t} else {\n\t\t\tconst resolvedType = this._storage.getByResourceIdentifier(\n\t\t\t\tcontext.projectKey,\n\t\t\t\ttype,\n\t\t\t);\n\t\t\tif (!resolvedType) {\n\t\t\t\tthrow new Error(`Type ${type} not found`);\n\t\t\t}\n\n\t\t\tlineItem.custom = {\n\t\t\t\ttype: {\n\t\t\t\t\ttypeId: \"type\",\n\t\t\t\t\tid: resolvedType.id,\n\t\t\t\t},\n\t\t\t\tfields: fields || {},\n\t\t\t};\n\t\t}\n\t}\n\n\tsetLocale(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Order>,\n\t\t{ locale }: OrderSetLocaleAction,\n\t) {\n\t\tresource.locale = locale;\n\t}\n\n\tsetOrderNumber(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Order>,\n\t\t{ orderNumber }: OrderSetOrderNumberAction,\n\t) {\n\t\tresource.orderNumber = orderNumber;\n\t}\n\n\tsetParcelCustomField(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Order>,\n\t\t{ parcelId, name, value }: OrderSetParcelCustomFieldAction,\n\t) {\n\t\tif (!resource.shippingInfo) {\n\t\t\tthrow new Error(\"Resource has no shipping info\");\n\t\t}\n\n\t\tfor (const delivery of resource.shippingInfo.deliveries || []) {\n\t\t\tfor (const parcel of delivery.parcels || []) {\n\t\t\t\tif (parcel.id === parcelId && parcel.custom?.fields) {\n\t\t\t\t\tparcel.custom.fields[name] = value;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tsetPurchaseOrderNumber(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Order>,\n\t\t{ purchaseOrderNumber }: OrderSetPurchaseOrderNumberAction,\n\t) {\n\t\tresource.purchaseOrderNumber = purchaseOrderNumber;\n\t}\n\n\tsetShippingAddress(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Order>,\n\t\t{ address }: OrderSetShippingAddressAction,\n\t) {\n\t\tresource.shippingAddress = createAddress(\n\t\t\taddress,\n\t\t\tcontext.projectKey,\n\t\t\tthis._storage,\n\t\t);\n\t}\n\n\tsetStore(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Order>,\n\t\t{ store }: OrderSetStoreAction,\n\t) {\n\t\tif (!store) return;\n\t\tconst resolvedType = this._storage.getByResourceIdentifier(\n\t\t\tcontext.projectKey,\n\t\t\tstore,\n\t\t);\n\t\tif (!resolvedType) {\n\t\t\tthrow new Error(`No store found with key=${store.key}`);\n\t\t}\n\n\t\tconst storeReference = resolvedType as Store;\n\t\tresource.store = {\n\t\t\ttypeId: \"store\",\n\t\t\tkey: storeReference.key,\n\t\t};\n\t}\n\n\ttransitionState(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Order>,\n\t\t{ state }: OrderTransitionStateAction,\n\t) {\n\t\tconst resolvedType = this._storage.getByResourceIdentifier(\n\t\t\tcontext.projectKey,\n\t\t\tstate,\n\t\t) as State | null;\n\n\t\tif (!resolvedType) {\n\t\t\tthrow new Error(\n\t\t\t\t`No state found with key=${state.key} or id=${state.key}`,\n\t\t\t);\n\t\t}\n\n\t\tresource.state = {\n\t\t\ttypeId: \"state\",\n\t\t\tid: resolvedType.id,\n\t\t\tobj: { ...resolvedType, key: state.key ?? \"\" },\n\t\t};\n\t}\n\n\tupdateSyncInfo(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Order>,\n\t\t{ channel, externalId, syncedAt }: OrderUpdateSyncInfoAction,\n\t) {\n\t\tif (!channel) return;\n\t\tconst resolvedType = this._storage.getByResourceIdentifier(\n\t\t\tcontext.projectKey,\n\t\t\tchannel,\n\t\t);\n\t\tif (!resolvedType) {\n\t\t\tthrow new Error(`Channel ${channel} not found`);\n\t\t}\n\n\t\tconst syncData: SyncInfo = {\n\t\t\tchannel: {\n\t\t\t\ttypeId: \"channel\",\n\t\t\t\tid: resolvedType.id,\n\t\t\t},\n\t\t\texternalId,\n\t\t\tsyncedAt: syncedAt ?? new Date().toISOString(),\n\t\t};\n\n\t\tif (!resource.syncInfo?.length) {\n\t\t\tresource.syncInfo = [syncData];\n\t\t} else {\n\t\t\tconst lastSyncInfo = resource.syncInfo[resource.syncInfo.length - 1];\n\t\t\tif (\n\t\t\t\tlastSyncInfo.channel.id !== syncData.channel.id ||\n\t\t\t\tlastSyncInfo.externalId !== syncData.externalId\n\t\t\t) {\n\t\t\t\tresource.syncInfo.push(syncData);\n\t\t\t}\n\t\t}\n\t}\n}\n","import assert from \"node:assert\";\nimport type {\n\tCart,\n\tCartReference,\n\tCustomLineItem,\n\tCustomLineItemImportDraft,\n\tGeneralError,\n\tLineItem,\n\tLineItemImportDraft,\n\tOrder,\n\tOrderFromCartDraft,\n\tOrderImportDraft,\n\tProduct,\n\tProductPagedQueryResponse,\n\tProductVariant,\n\tShippingInfo,\n\tShippingMethodDoesNotMatchCartError,\n\tShippingMethodReference,\n} from \"@commercetools/platform-sdk\";\nimport type { Config } from \"#src/config.ts\";\nimport { CommercetoolsError } from \"#src/exceptions.ts\";\nimport {\n\tgenerateRandomString,\n\tgetBaseResourceProperties,\n} from \"#src/helpers.ts\";\nimport {\n\tcalculateTaxedPriceFromRate,\n\tcalculateTaxTotals,\n} from \"#src/lib/tax.ts\";\nimport {\n\tcreateShippingInfoFromMethod,\n\tgetShippingMethodsMatchingCart,\n} from \"#src/shipping.ts\";\nimport type { Writable } from \"#src/types.ts\";\nimport type { RepositoryContext } from \"../abstract.ts\";\nimport { AbstractResourceRepository, type QueryParams } from \"../abstract.ts\";\nimport {\n\tcreateAddress,\n\tcreateCentPrecisionMoney,\n\tcreateCustomFields,\n\tcreatePrice,\n\tcreateTypedMoney,\n\tresolveStoreReference,\n} from \"../helpers.ts\";\nimport { OrderUpdateHandler } from \"./actions.ts\";\n\nexport class OrderRepository extends AbstractResourceRepository<\"order\"> {\n\tconstructor(config: Config) {\n\t\tsuper(\"order\", config);\n\t\tthis.actions = new OrderUpdateHandler(config.storage);\n\t}\n\n\tcreate(context: RepositoryContext, draft: OrderFromCartDraft): Order {\n\t\tassert(draft.cart, \"draft.cart is missing\");\n\t\treturn this.createFromCart(\n\t\t\tcontext,\n\t\t\t{\n\t\t\t\tid: draft.cart.id!,\n\t\t\t\ttypeId: \"cart\",\n\t\t\t},\n\t\t\tdraft.orderNumber,\n\t\t);\n\t}\n\n\tcreateFromCart(\n\t\tcontext: RepositoryContext,\n\t\tcartReference: CartReference,\n\t\torderNumber?: string,\n\t) {\n\t\tconst cart = this._storage.getByResourceIdentifier(\n\t\t\tcontext.projectKey,\n\t\t\tcartReference,\n\t\t) as Cart | null;\n\t\tif (!cart) {\n\t\t\tthrow new Error(\"Cannot find cart\");\n\t\t}\n\n\t\tconst resource: Writable<Order> = {\n\t\t\t...getBaseResourceProperties(),\n\t\t\tanonymousId: cart.anonymousId,\n\t\t\tbillingAddress: cart.billingAddress,\n\t\t\tcart: cartReference,\n\t\t\tcountry: cart.country,\n\t\t\tcustom: cart.custom,\n\t\t\tcustomerEmail: cart.customerEmail,\n\t\t\tcustomerGroup: cart.customerGroup,\n\t\t\tcustomerId: cart.customerId,\n\t\t\tcustomLineItems: [],\n\t\t\tdirectDiscounts: cart.directDiscounts,\n\t\t\tdiscountCodes: cart.discountCodes,\n\t\t\tdiscountOnTotalPrice: cart.discountOnTotalPrice,\n\t\t\tlastMessageSequenceNumber: 0,\n\t\t\tlineItems: cart.lineItems,\n\t\t\tlocale: cart.locale,\n\t\t\torderNumber: orderNumber ?? generateRandomString(10),\n\t\t\torderState: \"Open\",\n\t\t\torigin: \"Customer\",\n\t\t\tpaymentInfo: cart.paymentInfo,\n\t\t\trefusedGifts: [],\n\t\t\tshipping: cart.shipping,\n\t\t\tshippingAddress: cart.shippingAddress,\n\t\t\tshippingInfo: cart.shippingInfo,\n\t\t\tshippingMode: cart.shippingMode,\n\t\t\tsyncInfo: [],\n\t\t\ttaxCalculationMode: cart.taxCalculationMode,\n\t\t\ttaxedPrice: cart.taxedPrice,\n\t\t\ttaxedShippingPrice: cart.taxedShippingPrice,\n\t\t\ttaxMode: cart.taxMode,\n\t\t\ttaxRoundingMode: cart.taxRoundingMode,\n\t\t\ttotalPrice: cart.totalPrice,\n\t\t\tstore: cart.store,\n\t\t};\n\n\t\tconst { taxedPrice, taxedShippingPrice } = calculateTaxTotals({\n\t\t\tlineItems: cart.lineItems,\n\t\t\tcustomLineItems: cart.customLineItems,\n\t\t\tshippingInfo: cart.shippingInfo,\n\t\t\ttotalPrice: cart.totalPrice,\n\t\t});\n\t\tresource.taxedPrice = resource.taxedPrice ?? taxedPrice;\n\t\tresource.taxedShippingPrice =\n\t\t\tresource.taxedShippingPrice ?? taxedShippingPrice;\n\t\treturn this.saveNew(context, resource);\n\t}\n\n\timport(context: RepositoryContext, draft: OrderImportDraft): Order {\n\t\t// TODO: Check if order with given orderNumber already exists\n\t\tassert(this, \"OrderRepository not valid\");\n\t\tconst resource: Writable<Order> = {\n\t\t\t...getBaseResourceProperties(),\n\n\t\t\tbillingAddress: createAddress(\n\t\t\t\tdraft.billingAddress,\n\t\t\t\tcontext.projectKey,\n\t\t\t\tthis._storage,\n\t\t\t),\n\t\t\tshippingAddress: createAddress(\n\t\t\t\tdraft.shippingAddress,\n\t\t\t\tcontext.projectKey,\n\t\t\t\tthis._storage,\n\t\t\t),\n\n\t\t\tcustom: createCustomFields(\n\t\t\t\tdraft.custom,\n\t\t\t\tcontext.projectKey,\n\t\t\t\tthis._storage,\n\t\t\t),\n\t\t\tcustomerEmail: draft.customerEmail,\n\t\t\tcustomerId: draft.customerId,\n\t\t\tbusinessUnit: draft.businessUnit?.key\n\t\t\t\t? { typeId: \"business-unit\", key: draft.businessUnit.key }\n\t\t\t\t: undefined,\n\t\t\tlastMessageSequenceNumber: 0,\n\t\t\torderNumber: draft.orderNumber,\n\t\t\torderState: draft.orderState || \"Open\",\n\t\t\torigin: draft.origin || \"Customer\",\n\t\t\tpaymentState: draft.paymentState,\n\t\t\trefusedGifts: [],\n\t\t\tshippingMode: \"Single\",\n\t\t\tshipping: [],\n\t\t\tshippingInfo: undefined,\n\t\t\tstore: resolveStoreReference(\n\t\t\t\tdraft.store,\n\t\t\t\tcontext.projectKey,\n\t\t\t\tthis._storage,\n\t\t\t),\n\t\t\tsyncInfo: [],\n\n\t\t\tlineItems:\n\t\t\t\tdraft.lineItems?.map((item) =>\n\t\t\t\t\tthis.lineItemFromImportDraft.bind(this)(context, item),\n\t\t\t\t) || [],\n\t\t\tcustomLineItems:\n\t\t\t\tdraft.customLineItems?.map((item) =>\n\t\t\t\t\tthis.customLineItemFromImportDraft.bind(this)(context, item),\n\t\t\t\t) || [],\n\n\t\t\ttotalPrice: createCentPrecisionMoney(draft.totalPrice),\n\t\t};\n\n\t\t// Set shipping info after resource is created\n\t\tif (draft.shippingInfo?.shippingMethod) {\n\t\t\tconst { ...shippingMethodRef } = draft.shippingInfo.shippingMethod;\n\n\t\t\t// get id when reference is by key only\n\t\t\tif (shippingMethodRef.key && !shippingMethodRef.id) {\n\t\t\t\tconst shippingMethod =\n\t\t\t\t\tthis._storage.getByResourceIdentifier<\"shipping-method\">(\n\t\t\t\t\t\tcontext.projectKey,\n\t\t\t\t\t\tshippingMethodRef,\n\t\t\t\t\t);\n\t\t\t\tif (!shippingMethod) {\n\t\t\t\t\tthrow new CommercetoolsError<GeneralError>({\n\t\t\t\t\t\tcode: \"General\",\n\t\t\t\t\t\tmessage: `A shipping method with key '${shippingMethodRef.key}' does not exist.`,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tshippingMethodRef.id = shippingMethod.id;\n\t\t\t}\n\n\t\t\tresource.shippingInfo = this.createShippingInfo(context, resource, {\n\t\t\t\ttypeId: \"shipping-method\",\n\t\t\t\tid: shippingMethodRef.id as string,\n\t\t\t});\n\t\t}\n\n\t\tconst { taxedPrice, taxedShippingPrice } = calculateTaxTotals({\n\t\t\tlineItems: resource.lineItems,\n\t\t\tcustomLineItems: resource.customLineItems,\n\t\t\tshippingInfo: resource.shippingInfo,\n\t\t\ttotalPrice: resource.totalPrice,\n\t\t});\n\t\tresource.taxedPrice = resource.taxedPrice ?? taxedPrice;\n\t\tresource.taxedShippingPrice =\n\t\t\tresource.taxedShippingPrice ?? taxedShippingPrice;\n\n\t\treturn this.saveNew(context, resource);\n\t}\n\n\tprivate lineItemFromImportDraft(\n\t\tcontext: RepositoryContext,\n\t\tdraft: LineItemImportDraft,\n\t): LineItem {\n\t\tlet product: Product;\n\t\tlet variant: ProductVariant | undefined;\n\n\t\tif (draft.variant.sku) {\n\t\t\tvariant = {\n\t\t\t\tid: 0,\n\t\t\t\tsku: draft.variant.sku,\n\t\t\t};\n\n\t\t\tconst items = this._storage.query(context.projectKey, \"product\", {\n\t\t\t\twhere: [\n\t\t\t\t\t`masterData(current(masterVariant(sku=\"${draft.variant.sku}\"))) or masterData(current(variants(sku=\"${draft.variant.sku}\")))`,\n\t\t\t\t],\n\t\t\t}) as ProductPagedQueryResponse;\n\n\t\t\tif (items.count !== 1) {\n\t\t\t\tthrow new CommercetoolsError<GeneralError>({\n\t\t\t\t\tcode: \"General\",\n\t\t\t\t\tmessage: `A product containing a variant with SKU '${draft.variant.sku}' not found.`,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tproduct = items.results[0];\n\t\t\tif (product.masterData.current.masterVariant.sku === draft.variant.sku) {\n\t\t\t\tvariant = product.masterData.current.masterVariant;\n\t\t\t} else {\n\t\t\t\tvariant = product.masterData.current.variants.find(\n\t\t\t\t\t(v) => v.sku === draft.variant.sku,\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (!variant) {\n\t\t\t\tthrow new Error(\"Internal state error\");\n\t\t\t}\n\t\t} else {\n\t\t\tthrow new Error(\"No product found\");\n\t\t}\n\n\t\tconst quantity = draft.quantity ?? 1;\n\t\tconst totalPrice = createCentPrecisionMoney({\n\t\t\t...draft.price.value,\n\t\t\tcentAmount: (draft.price.value.centAmount ?? 0) * quantity,\n\t\t});\n\n\t\tconst lineItem: LineItem = {\n\t\t\t...getBaseResourceProperties(),\n\t\t\tcustom: createCustomFields(\n\t\t\t\tdraft.custom,\n\t\t\t\tcontext.projectKey,\n\t\t\t\tthis._storage,\n\t\t\t),\n\t\t\tdiscountedPricePerQuantity: [],\n\t\t\tlineItemMode: \"Standard\",\n\t\t\tname: draft.name,\n\t\t\tprice: createPrice(draft.price),\n\t\t\tpriceMode: \"Platform\",\n\t\t\tproductId: product.id,\n\t\t\tproductType: product.productType,\n\t\t\tquantity,\n\t\t\tstate: draft.state || [],\n\t\t\ttaxRate: draft.taxRate,\n\t\t\ttaxedPrice: calculateTaxedPriceFromRate(\n\t\t\t\ttotalPrice.centAmount,\n\t\t\t\ttotalPrice.currencyCode,\n\t\t\t\tdraft.taxRate,\n\t\t\t),\n\t\t\ttaxedPricePortions: [],\n\t\t\tperMethodTaxRate: [],\n\t\t\ttotalPrice,\n\t\t\tvariant: {\n\t\t\t\tid: variant.id,\n\t\t\t\tsku: variant.sku,\n\t\t\t\tprice: createPrice(draft.price),\n\t\t\t\tattributes: variant.attributes,\n\t\t\t},\n\t\t};\n\n\t\treturn lineItem;\n\t}\n\n\tprivate customLineItemFromImportDraft(\n\t\tcontext: RepositoryContext,\n\t\tdraft: CustomLineItemImportDraft,\n\t): CustomLineItem {\n\t\tconst quantity = draft.quantity ?? 1;\n\t\tconst totalPrice = createCentPrecisionMoney({\n\t\t\t...draft.money,\n\t\t\tcentAmount: (draft.money.centAmount ?? 0) * quantity,\n\t\t});\n\n\t\tconst lineItem: CustomLineItem = {\n\t\t\t...getBaseResourceProperties(),\n\t\t\tcustom: createCustomFields(\n\t\t\t\tdraft.custom,\n\t\t\t\tcontext.projectKey,\n\t\t\t\tthis._storage,\n\t\t\t),\n\t\t\tdiscountedPricePerQuantity: [],\n\t\t\tmoney: createTypedMoney(draft.money),\n\t\t\tname: draft.name,\n\t\t\tquantity,\n\t\t\tperMethodTaxRate: [],\n\t\t\tpriceMode: draft.priceMode ?? \"Standard\",\n\t\t\tslug: draft.slug,\n\t\t\tstate: [],\n\t\t\ttotalPrice,\n\t\t\ttaxedPrice: calculateTaxedPriceFromRate(\n\t\t\t\ttotalPrice.centAmount,\n\t\t\t\ttotalPrice.currencyCode,\n\t\t\t\tdraft.taxRate,\n\t\t\t),\n\t\t\ttaxedPricePortions: [],\n\t\t};\n\n\t\treturn lineItem;\n\t}\n\n\tgetWithOrderNumber(\n\t\tcontext: RepositoryContext,\n\t\torderNumber: string,\n\t\tparams: QueryParams = {},\n\t): Order | undefined {\n\t\tconst result = this._storage.query(context.projectKey, this.getTypeId(), {\n\t\t\t...params,\n\t\t\twhere: [`orderNumber=\"${orderNumber}\"`],\n\t\t});\n\t\tif (result.count === 1) {\n\t\t\treturn result.results[0] as Order;\n\t\t}\n\n\t\t// Catch this for now, should be checked when creating/updating\n\t\tif (result.count > 1) {\n\t\t\tthrow new Error(\"Duplicate order numbers\");\n\t\t}\n\n\t\treturn;\n\t}\n\n\tcreateShippingInfo(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Order>,\n\t\tshippingMethodRef: ShippingMethodReference,\n\t): ShippingInfo {\n\t\tconst cartLikeForMatching: Writable<Cart> = {\n\t\t\t...resource,\n\t\t\tcartState: \"Active\" as const,\n\t\t\tinventoryMode: \"None\" as const,\n\t\t\titemShippingAddresses: [],\n\t\t\tpriceRoundingMode: resource.taxRoundingMode || \"HalfEven\",\n\t\t\ttaxMode: resource.taxMode || \"Platform\",\n\t\t\ttaxCalculationMode: resource.taxCalculationMode || \"LineItemLevel\",\n\t\t\ttaxRoundingMode: resource.taxRoundingMode || \"HalfEven\",\n\t\t\tdiscountCodes: resource.discountCodes || [],\n\t\t\tdirectDiscounts: resource.directDiscounts || [],\n\t\t\tshippingInfo: undefined,\n\t\t};\n\n\t\tconst shippingMethods = getShippingMethodsMatchingCart(\n\t\t\tcontext,\n\t\t\tthis._storage,\n\t\t\tcartLikeForMatching,\n\t\t\t{\n\t\t\t\texpand: [\"zoneRates[*].zone\"],\n\t\t\t},\n\t\t);\n\n\t\tconst method = shippingMethods.results.find(\n\t\t\t(candidate) => candidate.id === shippingMethodRef.id,\n\t\t);\n\n\t\tif (!method) {\n\t\t\tthrow new CommercetoolsError<ShippingMethodDoesNotMatchCartError>({\n\t\t\t\tcode: \"ShippingMethodDoesNotMatchCart\",\n\t\t\t\tmessage: `The shipping method with ID '${shippingMethodRef.id}' is not allowed for the order with ID '${resource.id}'.`,\n\t\t\t});\n\t\t}\n\n\t\tconst baseShippingInfo = createShippingInfoFromMethod(\n\t\t\tcontext,\n\t\t\tthis._storage,\n\t\t\tresource,\n\t\t\tmethod,\n\t\t);\n\n\t\treturn {\n\t\t\t...baseShippingInfo,\n\t\t\tdeliveries: [],\n\t\t};\n\t}\n}\n","import type {\n\tInvalidJsonInputError,\n\tQuoteRequest,\n\tQuoteRequestSetCustomFieldAction,\n\tQuoteRequestSetCustomTypeAction,\n\tQuoteRequestTransitionStateAction,\n\tQuoteRequestUpdateAction,\n\tStateReference,\n} from \"@commercetools/platform-sdk\";\nimport { CommercetoolsError } from \"#src/exceptions.ts\";\nimport type { Writable } from \"#src/types.ts\";\nimport type { RepositoryContext, UpdateHandlerInterface } from \"../abstract.ts\";\nimport { AbstractUpdateHandler } from \"../abstract.ts\";\nimport { getReferenceFromResourceIdentifier } from \"../helpers.ts\";\n\nexport class QuoteRequestUpdateHandler\n\textends AbstractUpdateHandler\n\timplements\n\t\tPartial<UpdateHandlerInterface<QuoteRequest, QuoteRequestUpdateAction>>\n{\n\tsetCustomField(\n\t\tcontext: RepositoryContext,\n\t\tresource: QuoteRequest,\n\t\t{ name, value }: QuoteRequestSetCustomFieldAction,\n\t) {\n\t\tif (!resource.custom) {\n\t\t\tthrow new Error(\"Resource has no custom field\");\n\t\t}\n\t\tresource.custom.fields[name] = value;\n\t}\n\n\tsetCustomType(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<QuoteRequest>,\n\t\t{ type, fields }: QuoteRequestSetCustomTypeAction,\n\t) {\n\t\tif (!type) {\n\t\t\tresource.custom = undefined;\n\t\t} else {\n\t\t\tconst resolvedType = this._storage.getByResourceIdentifier(\n\t\t\t\tcontext.projectKey,\n\t\t\t\ttype,\n\t\t\t);\n\t\t\tif (!resolvedType) {\n\t\t\t\tthrow new Error(`Type ${type} not found`);\n\t\t\t}\n\n\t\t\tresource.custom = {\n\t\t\t\ttype: {\n\t\t\t\t\ttypeId: \"type\",\n\t\t\t\t\tid: resolvedType.id,\n\t\t\t\t},\n\t\t\t\tfields: fields || {},\n\t\t\t};\n\t\t}\n\t}\n\n\ttransitionState(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<QuoteRequest>,\n\t\t{ state, force }: QuoteRequestTransitionStateAction,\n\t) {\n\t\tlet stateReference: StateReference | undefined;\n\t\tif (state) {\n\t\t\tstateReference = getReferenceFromResourceIdentifier<StateReference>(\n\t\t\t\tstate,\n\t\t\t\tcontext.projectKey,\n\t\t\t\tthis._storage,\n\t\t\t);\n\t\t\tresource.state = stateReference;\n\t\t} else {\n\t\t\tthrow new CommercetoolsError<InvalidJsonInputError>(\n\t\t\t\t{\n\t\t\t\t\tcode: \"InvalidJsonInput\",\n\t\t\t\t\tmessage: \"Request body does not contain valid JSON.\",\n\t\t\t\t\tdetailedErrorMessage: \"actions -> state: Missing required value\",\n\t\t\t\t},\n\t\t\t\t400,\n\t\t\t);\n\t\t}\n\n\t\treturn resource;\n\t}\n}\n","import assert from \"node:assert\";\nimport type {\n\tCart,\n\tCartReference,\n\tMyQuoteRequestDraft,\n\tQuoteRequest,\n\tQuoteRequestDraft,\n} from \"@commercetools/platform-sdk\";\nimport type { Config } from \"#src/config.ts\";\nimport { getBaseResourceProperties } from \"#src/helpers.ts\";\nimport type { RepositoryContext } from \"../abstract.ts\";\nimport { AbstractResourceRepository } from \"../abstract.ts\";\nimport { QuoteRequestUpdateHandler } from \"./actions.ts\";\n\nexport class QuoteRequestRepository extends AbstractResourceRepository<\"quote-request\"> {\n\tconstructor(config: Config) {\n\t\tsuper(\"quote-request\", config);\n\t\tthis.actions = new QuoteRequestUpdateHandler(config.storage);\n\t}\n\n\tcreate(\n\t\tcontext: RepositoryContext,\n\t\tdraft: QuoteRequestDraft | MyQuoteRequestDraft,\n\t): QuoteRequest {\n\t\t// Handle the 'my' version of the draft\n\t\tif (\"cartId\" in draft) {\n\t\t\treturn this.createFromCart(context, {\n\t\t\t\tid: draft.cartId,\n\t\t\t\ttypeId: \"cart\",\n\t\t\t});\n\t\t}\n\n\t\tassert(draft.cart, \"draft.cart is missing\");\n\t\treturn this.createFromCart(context, {\n\t\t\tid: draft.cart.id!,\n\t\t\ttypeId: \"cart\",\n\t\t});\n\t}\n\n\tcreateFromCart(context: RepositoryContext, cartReference: CartReference) {\n\t\tconst cart = this._storage.getByResourceIdentifier(\n\t\t\tcontext.projectKey,\n\t\t\tcartReference,\n\t\t) as Cart | null;\n\t\tif (!cart) {\n\t\t\tthrow new Error(\"Cannot find cart\");\n\t\t}\n\n\t\tif (!cart.customerId) {\n\t\t\tthrow new Error(\"Cart does not have a customer\");\n\t\t}\n\n\t\tconst resource: QuoteRequest = {\n\t\t\t...getBaseResourceProperties(),\n\t\t\tbillingAddress: cart.billingAddress,\n\t\t\tcart: cartReference,\n\t\t\tcountry: cart.country,\n\t\t\tcustom: cart.custom,\n\t\t\tcustomer: {\n\t\t\t\ttypeId: \"customer\",\n\t\t\t\tid: cart.customerId,\n\t\t\t},\n\t\t\tcustomerGroup: cart.customerGroup,\n\t\t\tcustomLineItems: [],\n\t\t\tdirectDiscounts: cart.directDiscounts,\n\t\t\tlineItems: cart.lineItems,\n\t\t\tpaymentInfo: cart.paymentInfo,\n\t\t\tpriceRoundingMode: cart.priceRoundingMode,\n\t\t\tquoteRequestState: \"Submitted\",\n\t\t\tshippingAddress: cart.shippingAddress,\n\t\t\ttaxCalculationMode: cart.taxCalculationMode,\n\t\t\ttaxedPrice: cart.taxedPrice,\n\t\t\ttaxMode: cart.taxMode,\n\t\t\ttaxRoundingMode: cart.taxRoundingMode,\n\t\t\ttotalPrice: cart.totalPrice,\n\t\t\tstore: cart.store,\n\t\t};\n\t\treturn this.saveNew(context, resource);\n\t}\n}\n","import { CartRepository } from \"./cart/index.ts\";\nimport { OrderRepository } from \"./order/index.ts\";\nimport { QuoteRequestRepository } from \"./quote-request/index.ts\";\n\nexport class AsAssociateOrderRepository extends OrderRepository {}\nexport class AsAssociateCartRepository extends CartRepository {}\nexport class AsAssociateQuoteRequestRepository extends QuoteRequestRepository {}\n","import type {\n\tAssociateRole,\n\tAssociateRoleAddPermissionAction,\n\tAssociateRoleChangeBuyerAssignableAction,\n\tAssociateRoleDraft,\n\tAssociateRoleRemovePermissionAction,\n\tAssociateRoleSetCustomFieldAction,\n\tAssociateRoleSetCustomTypeAction,\n\tAssociateRoleSetNameAction,\n\tAssociateRoleSetPermissionsAction,\n\tAssociateRoleUpdateAction,\n} from \"@commercetools/platform-sdk\";\nimport type { Config } from \"#src/config.ts\";\nimport { getBaseResourceProperties } from \"../helpers.ts\";\nimport type { Writable } from \"../types.ts\";\nimport type { UpdateHandlerInterface } from \"./abstract.ts\";\nimport {\n\tAbstractResourceRepository,\n\tAbstractUpdateHandler,\n\ttype RepositoryContext,\n} from \"./abstract.ts\";\nimport { createCustomFields } from \"./helpers.ts\";\n\nexport class AssociateRoleRepository extends AbstractResourceRepository<\"associate-role\"> {\n\tconstructor(config: Config) {\n\t\tsuper(\"associate-role\", config);\n\t\tthis.actions = new AssociateRoleUpdateHandler(this._storage);\n\t}\n\n\tcreate(context: RepositoryContext, draft: AssociateRoleDraft): AssociateRole {\n\t\tconst resource: AssociateRole = {\n\t\t\t...getBaseResourceProperties(),\n\t\t\tkey: draft.key,\n\t\t\tname: draft.name,\n\t\t\tbuyerAssignable: draft.buyerAssignable || false,\n\t\t\tpermissions: draft.permissions || [],\n\t\t\tcustom: createCustomFields(\n\t\t\t\tdraft.custom,\n\t\t\t\tcontext.projectKey,\n\t\t\t\tthis._storage,\n\t\t\t),\n\t\t};\n\n\t\treturn this.saveNew(context, resource);\n\t}\n}\n\nclass AssociateRoleUpdateHandler\n\textends AbstractUpdateHandler\n\timplements\n\t\tPartial<UpdateHandlerInterface<AssociateRole, AssociateRoleUpdateAction>>\n{\n\taddPermission(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<AssociateRole>,\n\t\t{ permission }: AssociateRoleAddPermissionAction,\n\t) {\n\t\tif (!resource.permissions) {\n\t\t\tresource.permissions = [permission];\n\t\t} else {\n\t\t\tresource.permissions.push(permission);\n\t\t}\n\t}\n\n\tchangeBuyerAssignable(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<AssociateRole>,\n\t\t{ buyerAssignable }: AssociateRoleChangeBuyerAssignableAction,\n\t) {\n\t\tresource.buyerAssignable = buyerAssignable;\n\t}\n\n\tremovePermission(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<AssociateRole>,\n\t\t{ permission }: AssociateRoleRemovePermissionAction,\n\t) {\n\t\tif (!resource.permissions) {\n\t\t\treturn;\n\t\t}\n\n\t\tresource.permissions = resource.permissions.filter((p) => p !== permission);\n\t}\n\n\tsetBuyerAssignable(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<AssociateRole>,\n\t\t{ buyerAssignable }: AssociateRoleChangeBuyerAssignableAction,\n\t) {\n\t\tresource.buyerAssignable = buyerAssignable;\n\t}\n\n\tsetCustomFields(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<AssociateRole>,\n\t\t{ name, value }: AssociateRoleSetCustomFieldAction,\n\t) {\n\t\tif (!resource.custom) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (value === null) {\n\t\t\tdelete resource.custom.fields[name];\n\t\t} else {\n\t\t\tresource.custom.fields[name] = value;\n\t\t}\n\t}\n\n\tsetCustomType(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<AssociateRole>,\n\t\t{ type, fields }: AssociateRoleSetCustomTypeAction,\n\t) {\n\t\tif (type) {\n\t\t\tresource.custom = createCustomFields(\n\t\t\t\t{ type, fields },\n\t\t\t\tcontext.projectKey,\n\t\t\t\tthis._storage,\n\t\t\t);\n\t\t} else {\n\t\t\tresource.custom = undefined;\n\t\t}\n\t}\n\n\tsetName(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<AssociateRole>,\n\t\t{ name }: AssociateRoleSetNameAction,\n\t) {\n\t\tresource.name = name;\n\t}\n\n\tsetPermissions(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<AssociateRole>,\n\t\t{ permissions }: AssociateRoleSetPermissionsAction,\n\t) {\n\t\tresource.permissions = permissions || [];\n\t}\n}\n","import type {\n\tAttributeGroup,\n\tAttributeGroupChangeNameAction,\n\tAttributeGroupDraft,\n\tAttributeGroupSetAttributesAction,\n\tAttributeGroupSetDescriptionAction,\n\tAttributeGroupSetKeyAction,\n\tAttributeGroupUpdateAction,\n} from \"@commercetools/platform-sdk\";\nimport type { Config } from \"#src/config.ts\";\nimport { getBaseResourceProperties } from \"../helpers.ts\";\nimport type { Writable } from \"../types.ts\";\nimport type { UpdateHandlerInterface } from \"./abstract.ts\";\nimport {\n\tAbstractResourceRepository,\n\tAbstractUpdateHandler,\n\ttype RepositoryContext,\n} from \"./abstract.ts\";\n\nexport class AttributeGroupRepository extends AbstractResourceRepository<\"attribute-group\"> {\n\tconstructor(config: Config) {\n\t\tsuper(\"attribute-group\", config);\n\t\tthis.actions = new AttributeGroupUpdateHandler(this._storage);\n\t}\n\n\tcreate(\n\t\tcontext: RepositoryContext,\n\t\tdraft: AttributeGroupDraft,\n\t): AttributeGroup {\n\t\tconst resource: AttributeGroup = {\n\t\t\t...getBaseResourceProperties(),\n\t\t\tname: draft.name,\n\t\t\tdescription: draft.description,\n\t\t\tkey: draft.key,\n\t\t\tattributes: draft.attributes,\n\t\t};\n\t\treturn this.saveNew(context, resource);\n\t}\n}\n\nclass AttributeGroupUpdateHandler\n\textends AbstractUpdateHandler\n\timplements\n\t\tPartial<UpdateHandlerInterface<AttributeGroup, AttributeGroupUpdateAction>>\n{\n\tchangeName(\n\t\t_context: RepositoryContext,\n\t\tresource: Writable<AttributeGroup>,\n\t\t{ name }: AttributeGroupChangeNameAction,\n\t) {\n\t\tresource.name = name;\n\t}\n\n\tsetAttributes(\n\t\t_context: RepositoryContext,\n\t\tresource: Writable<AttributeGroup>,\n\t\t{ attributes }: AttributeGroupSetAttributesAction,\n\t) {\n\t\tresource.attributes = attributes;\n\t}\n\n\tsetDescription(\n\t\t_context: RepositoryContext,\n\t\tresource: Writable<AttributeGroup>,\n\t\t{ description }: AttributeGroupSetDescriptionAction,\n\t) {\n\t\tresource.description = description;\n\t}\n\n\tsetKey(\n\t\t_context: RepositoryContext,\n\t\tresource: Writable<AttributeGroup>,\n\t\t{ key }: AttributeGroupSetKeyAction,\n\t) {\n\t\tresource.key = key;\n\t}\n}\n","import type {\n\tAssociate,\n\tBusinessUnit,\n\tBusinessUnitAddAddressAction,\n\tBusinessUnitAddAssociateAction,\n\tBusinessUnitAddBillingAddressIdAction,\n\tBusinessUnitAddShippingAddressIdAction,\n\tBusinessUnitAddStoreAction,\n\tBusinessUnitChangeAddressAction,\n\tBusinessUnitChangeApprovalRuleModeAction,\n\tBusinessUnitChangeAssociateAction,\n\tBusinessUnitChangeAssociateModeAction,\n\tBusinessUnitChangeNameAction,\n\tBusinessUnitChangeParentUnitAction,\n\tBusinessUnitChangeStatusAction,\n\tBusinessUnitDraft,\n\tBusinessUnitRemoveAddressAction,\n\tBusinessUnitRemoveAssociateAction,\n\tBusinessUnitRemoveBillingAddressIdAction,\n\tBusinessUnitRemoveShippingAddressIdAction,\n\tBusinessUnitSetAddressCustomFieldAction,\n\tBusinessUnitSetAddressCustomTypeAction,\n\tBusinessUnitSetAssociatesAction,\n\tBusinessUnitSetContactEmailAction,\n\tBusinessUnitSetCustomFieldAction,\n\tBusinessUnitSetCustomTypeAction,\n\tBusinessUnitSetDefaultBillingAddressAction,\n\tBusinessUnitSetDefaultShippingAddressAction,\n\tBusinessUnitSetStoreModeAction,\n\tBusinessUnitUpdateAction,\n\tCompany,\n\tCompanyDraft,\n\tDivision,\n\tDivisionDraft,\n} from \"@commercetools/platform-sdk\";\nimport type { Config } from \"#src/config.ts\";\nimport { generateRandomString, getBaseResourceProperties } from \"../helpers.ts\";\nimport type { Writable } from \"../types.ts\";\nimport type { UpdateHandlerInterface } from \"./abstract.ts\";\nimport {\n\tAbstractResourceRepository,\n\tAbstractUpdateHandler,\n\ttype RepositoryContext,\n} from \"./abstract.ts\";\nimport {\n\tcreateAddress,\n\tcreateAssociate,\n\tcreateCustomFields,\n\tgetBusinessUnitKeyReference,\n\tgetStoreKeyReference,\n} from \"./helpers.ts\";\n\nexport class BusinessUnitRepository extends AbstractResourceRepository<\"business-unit\"> {\n\tconstructor(config: Config) {\n\t\tsuper(\"business-unit\", config);\n\t\tthis.actions = new BusinessUnitUpdateHandler(this._storage);\n\t}\n\n\tcreate(context: RepositoryContext, draft: BusinessUnitDraft): BusinessUnit {\n\t\tconst addresses =\n\t\t\tdraft.addresses?.map((address) => ({\n\t\t\t\t...address,\n\t\t\t\tid: generateRandomString(5),\n\t\t\t})) ?? [];\n\n\t\tconst defaultBillingAddressId =\n\t\t\taddresses.length > 0 && draft.defaultBillingAddress !== undefined\n\t\t\t\t? addresses[draft.defaultBillingAddress].id\n\t\t\t\t: undefined;\n\t\tconst defaultShippingAddressId =\n\t\t\taddresses.length > 0 && draft.defaultShippingAddress !== undefined\n\t\t\t\t? addresses[draft.defaultShippingAddress].id\n\t\t\t\t: undefined;\n\n\t\tconst shippingAddressIds = draft.shippingAddresses?.map(\n\t\t\t(i) => addresses[i].id,\n\t\t);\n\t\tconst billingAddressIds = draft.billingAddresses?.map(\n\t\t\t(i) => addresses[i].id,\n\t\t);\n\n\t\tconst resource = {\n\t\t\t...getBaseResourceProperties(),\n\t\t\tkey: draft.key,\n\t\t\tstatus: draft.status,\n\t\t\tstores: draft.stores?.map((s) =>\n\t\t\t\tgetStoreKeyReference(s, context.projectKey, this._storage),\n\t\t\t),\n\t\t\tstoreMode: draft.storeMode,\n\t\t\tname: draft.name,\n\t\t\tcontactEmail: draft.contactEmail,\n\t\t\taddresses: addresses,\n\t\t\tcustom: createCustomFields(\n\t\t\t\tdraft.custom,\n\t\t\t\tcontext.projectKey,\n\t\t\t\tthis._storage,\n\t\t\t),\n\t\t\tshippingAddressIds: shippingAddressIds,\n\t\t\tbillingAddressIds: billingAddressIds,\n\t\t\tdefaultShippingAddressId: defaultShippingAddressId,\n\t\t\tdefaultBillingAddressId: defaultBillingAddressId,\n\t\t\tassociateMode: draft.associateMode,\n\t\t\tapprovalRuleMode: draft.approvalRuleMode,\n\n\t\t\tassociates:\n\t\t\t\tdraft.associates?.map((a) =>\n\t\t\t\t\tcreateAssociate(a, context.projectKey, this._storage),\n\t\t\t\t) ?? [],\n\t\t};\n\n\t\tif (this._isDivisionDraft(draft)) {\n\t\t\tconst division = {\n\t\t\t\t...resource,\n\t\t\t\tunitType: \"Division\" as const,\n\t\t\t\tparentUnit: getBusinessUnitKeyReference(\n\t\t\t\t\tdraft.parentUnit,\n\t\t\t\t\tcontext.projectKey,\n\t\t\t\t\tthis._storage,\n\t\t\t\t),\n\t\t\t} as Division;\n\n\t\t\tthis.saveNew(context, division);\n\t\t\treturn division;\n\t\t}\n\t\tif (this._isCompanyDraft(draft)) {\n\t\t\tconst company = {\n\t\t\t\t...resource,\n\t\t\t\tunitType: \"Company\" as const,\n\t\t\t} as Company;\n\n\t\t\tthis.saveNew(context, company);\n\t\t\treturn company;\n\t\t}\n\n\t\tthrow new Error(\"Invalid business unit type\");\n\t}\n\n\tprivate _isCompanyDraft(draft: BusinessUnitDraft): draft is CompanyDraft {\n\t\treturn draft.unitType === \"Company\";\n\t}\n\n\tprivate _isDivisionDraft(draft: BusinessUnitDraft): draft is DivisionDraft {\n\t\treturn draft.unitType === \"Division\";\n\t}\n}\n\nclass BusinessUnitUpdateHandler\n\textends AbstractUpdateHandler\n\timplements\n\t\tPartial<UpdateHandlerInterface<BusinessUnit, BusinessUnitUpdateAction>>\n{\n\taddAddress(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<BusinessUnit>,\n\t\t{ address }: BusinessUnitAddAddressAction,\n\t) {\n\t\tconst newAddress = createAddress(\n\t\t\taddress,\n\t\t\tcontext.projectKey,\n\t\t\tthis._storage,\n\t\t);\n\t\tif (newAddress) {\n\t\t\tresource.addresses.push(newAddress);\n\t\t}\n\t}\n\n\taddAssociate(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<BusinessUnit>,\n\t\t{ associate }: BusinessUnitAddAssociateAction,\n\t) {\n\t\tconst newAssociate = createAssociate(\n\t\t\tassociate,\n\t\t\tcontext.projectKey,\n\t\t\tthis._storage,\n\t\t);\n\t\tif (newAssociate) {\n\t\t\tresource.associates.push(newAssociate);\n\t\t}\n\t}\n\n\taddStore(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<BusinessUnit>,\n\t\t{ store }: BusinessUnitAddStoreAction,\n\t) {\n\t\tconst newStore = getStoreKeyReference(\n\t\t\tstore,\n\t\t\tcontext.projectKey,\n\t\t\tthis._storage,\n\t\t);\n\t\tif (newStore) {\n\t\t\tif (!resource.stores) {\n\t\t\t\tresource.stores = [];\n\t\t\t}\n\n\t\t\tresource.stores.push(newStore);\n\t\t}\n\t}\n\n\tchangeAddress(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<BusinessUnit>,\n\t\t{ addressId, address }: BusinessUnitChangeAddressAction,\n\t) {\n\t\tconst existingAddressIndex = resource.addresses.findIndex(\n\t\t\t(addr) => addr.id === addressId,\n\t\t);\n\t\tif (existingAddressIndex === -1) {\n\t\t\tthrow new Error(`Address with id ${addressId} not found`);\n\t\t}\n\n\t\tconst newAddress = createAddress(\n\t\t\taddress,\n\t\t\tcontext.projectKey,\n\t\t\tthis._storage,\n\t\t);\n\t\tif (newAddress) {\n\t\t\tresource.addresses[existingAddressIndex] = {\n\t\t\t\t...newAddress,\n\t\t\t\tid: addressId,\n\t\t\t};\n\t\t}\n\t}\n\n\tchangeApprovalRuleMode(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<BusinessUnit>,\n\t\t{ approvalRuleMode }: BusinessUnitChangeApprovalRuleModeAction,\n\t) {\n\t\tresource.approvalRuleMode = approvalRuleMode;\n\t}\n\n\tchangeAssociateMode(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<BusinessUnit>,\n\t\t{ associateMode }: BusinessUnitChangeAssociateModeAction,\n\t) {\n\t\tresource.associateMode = associateMode;\n\t}\n\n\tchangeName(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<BusinessUnit>,\n\t\t{ name }: BusinessUnitChangeNameAction,\n\t) {\n\t\tresource.name = name;\n\t}\n\n\tchangeParentUnit(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<BusinessUnit>,\n\t\t{ parentUnit }: BusinessUnitChangeParentUnitAction,\n\t) {\n\t\tresource.parentUnit = getBusinessUnitKeyReference(\n\t\t\tparentUnit,\n\t\t\tcontext.projectKey,\n\t\t\tthis._storage,\n\t\t);\n\t}\n\n\tchangeStatus(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<BusinessUnit>,\n\t\t{ status }: BusinessUnitChangeStatusAction,\n\t) {\n\t\tresource.status = status;\n\t}\n\n\tsetAssociates(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<BusinessUnit>,\n\t\t{ associates }: BusinessUnitSetAssociatesAction,\n\t) {\n\t\tconst newAssociates = associates\n\t\t\t.map((a) => createAssociate(a, context.projectKey, this._storage))\n\t\t\t.filter((a): a is Writable<Associate> => a !== undefined);\n\t\tresource.associates = newAssociates || undefined;\n\t}\n\n\tremoveAssociate(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<BusinessUnit>,\n\t\t{ customer }: BusinessUnitRemoveAssociateAction,\n\t) {\n\t\tresource.associates = resource.associates.filter(\n\t\t\t(associate) => associate.customer.id !== customer.id,\n\t\t);\n\t}\n\n\tchangeAssociate(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<BusinessUnit>,\n\t\t{ associate }: BusinessUnitChangeAssociateAction,\n\t) {\n\t\tconst existingAssociateIndex = resource.associates.findIndex(\n\t\t\t(a) => a.customer.id === associate.customer.id,\n\t\t);\n\t\tif (existingAssociateIndex === -1) {\n\t\t\tthrow new Error(\n\t\t\t\t`Associate with customer id ${associate.customer.id} not found`,\n\t\t\t);\n\t\t}\n\n\t\tconst newAssociate = createAssociate(\n\t\t\tassociate,\n\t\t\tcontext.projectKey,\n\t\t\tthis._storage,\n\t\t);\n\t\tif (newAssociate) {\n\t\t\tresource.associates[existingAssociateIndex] = newAssociate;\n\t\t}\n\t}\n\n\tsetContactEmail(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<BusinessUnit>,\n\t\t{ contactEmail }: BusinessUnitSetContactEmailAction,\n\t) {\n\t\tresource.contactEmail = contactEmail;\n\t}\n\n\tsetCustomType(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<BusinessUnit>,\n\t\t{ type, fields }: BusinessUnitSetCustomTypeAction,\n\t) {\n\t\tif (type) {\n\t\t\tresource.custom = createCustomFields(\n\t\t\t\t{ type, fields },\n\t\t\t\tcontext.projectKey,\n\t\t\t\tthis._storage,\n\t\t\t);\n\t\t} else {\n\t\t\tresource.custom = undefined;\n\t\t}\n\t}\n\n\tsetStoreMode(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<BusinessUnit>,\n\t\t{ storeMode }: BusinessUnitSetStoreModeAction,\n\t) {\n\t\tresource.storeMode = storeMode;\n\t}\n\n\tsetDefaultShippingAddress(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<BusinessUnit>,\n\t\t{ addressId }: BusinessUnitSetDefaultShippingAddressAction,\n\t) {\n\t\tresource.defaultShippingAddressId = addressId;\n\t}\n\n\taddShippingAddressId(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<BusinessUnit>,\n\t\t{ addressId }: BusinessUnitAddShippingAddressIdAction,\n\t) {\n\t\tif (!resource.shippingAddressIds) {\n\t\t\tresource.shippingAddressIds = [];\n\t\t}\n\t\tif (addressId) {\n\t\t\tresource.shippingAddressIds.push(addressId);\n\t\t}\n\t}\n\n\tremoveShippingAddressId(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<BusinessUnit>,\n\t\t{ addressId }: BusinessUnitRemoveShippingAddressIdAction,\n\t) {\n\t\tif (resource.shippingAddressIds) {\n\t\t\tresource.shippingAddressIds = resource.shippingAddressIds.filter(\n\t\t\t\t(id) => id !== addressId,\n\t\t\t);\n\t\t}\n\t\tif (resource.defaultShippingAddressId === addressId) {\n\t\t\tresource.defaultShippingAddressId = undefined;\n\t\t}\n\t}\n\n\taddBillingAddressId(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<BusinessUnit>,\n\t\t{ addressId }: BusinessUnitAddBillingAddressIdAction,\n\t) {\n\t\tif (!resource.billingAddressIds) {\n\t\t\tresource.billingAddressIds = [];\n\t\t}\n\t\tif (addressId) {\n\t\t\tresource.billingAddressIds.push(addressId);\n\t\t}\n\t}\n\n\tremoveBillingAddressId(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<BusinessUnit>,\n\t\t{ addressId }: BusinessUnitRemoveBillingAddressIdAction,\n\t) {\n\t\tif (resource.billingAddressIds) {\n\t\t\tresource.billingAddressIds = resource.billingAddressIds.filter(\n\t\t\t\t(id) => id !== addressId,\n\t\t\t);\n\t\t}\n\t\tif (resource.defaultBillingAddressId === addressId) {\n\t\t\tresource.defaultBillingAddressId = undefined;\n\t\t}\n\t}\n\n\tsetDefaultBillingAddress(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<BusinessUnit>,\n\t\t{ addressId }: BusinessUnitSetDefaultBillingAddressAction,\n\t) {\n\t\tresource.defaultBillingAddressId = addressId;\n\t}\n\n\tsetCustomField(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<BusinessUnit>,\n\t\t{ name, value }: BusinessUnitSetCustomFieldAction,\n\t) {\n\t\tif (!resource.custom) {\n\t\t\tthrow new Error(\"Resource has no custom type\");\n\t\t}\n\t\tresource.custom.fields[name] = value;\n\t}\n\n\tsetAddressCustomField(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<BusinessUnit>,\n\t\t{ addressId, name, value }: BusinessUnitSetAddressCustomFieldAction,\n\t) {\n\t\tconst address = resource.addresses.find((addr) => addr.id === addressId);\n\t\tif (!address) {\n\t\t\tthrow new Error(`Address with id ${addressId} not found`);\n\t\t}\n\t\tif (!address.custom) {\n\t\t\t// If the address doesn't have custom fields, we need to initialize them\n\t\t\t// This might require a type to be set first, but we'll just create minimal structure\n\t\t\tthrow new Error(\n\t\t\t\t\"Address has no custom type set. Use setAddressCustomType first.\",\n\t\t\t);\n\t\t}\n\t\taddress.custom.fields[name] = value;\n\t}\n\n\tsetAddressCustomType(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<BusinessUnit>,\n\t\t{ addressId, type, fields }: BusinessUnitSetAddressCustomTypeAction,\n\t) {\n\t\tconst address = resource.addresses.find((addr) => addr.id === addressId);\n\t\tif (!address) {\n\t\t\tthrow new Error(`Address with id ${addressId} not found`);\n\t\t}\n\n\t\tif (!type) {\n\t\t\taddress.custom = undefined;\n\t\t} else {\n\t\t\taddress.custom = createCustomFields(\n\t\t\t\t{ type, fields },\n\t\t\t\tcontext.projectKey,\n\t\t\t\tthis._storage,\n\t\t\t);\n\t\t}\n\t}\n\n\tremoveAddress(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<BusinessUnit>,\n\t\t{ addressId }: BusinessUnitRemoveAddressAction,\n\t) {\n\t\tresource.addresses = resource.addresses.filter(\n\t\t\t(addr) => addr.id !== addressId,\n\t\t);\n\n\t\tif (resource.shippingAddressIds) {\n\t\t\tresource.shippingAddressIds = resource.shippingAddressIds.filter(\n\t\t\t\t(id) => id !== addressId,\n\t\t\t);\n\t\t}\n\t\tif (resource.billingAddressIds) {\n\t\t\tresource.billingAddressIds = resource.billingAddressIds.filter(\n\t\t\t\t(id) => id !== addressId,\n\t\t\t);\n\t\t}\n\n\t\tif (resource.defaultShippingAddressId === addressId) {\n\t\t\tresource.defaultShippingAddressId = undefined;\n\t\t}\n\t\tif (resource.defaultBillingAddressId === addressId) {\n\t\t\tresource.defaultBillingAddressId = undefined;\n\t\t}\n\t}\n}\n","import type {\n\tCartDiscount,\n\tCartDiscountChangeIsActiveAction,\n\tCartDiscountChangeSortOrderAction,\n\tCartDiscountChangeTargetAction,\n\tCartDiscountSetCustomFieldAction,\n\tCartDiscountSetCustomTypeAction,\n\tCartDiscountSetDescriptionAction,\n\tCartDiscountSetKeyAction,\n\tCartDiscountSetStoresAction,\n\tCartDiscountSetValidFromAction,\n\tCartDiscountSetValidFromAndUntilAction,\n\tCartDiscountSetValidUntilAction,\n\tCartDiscountUpdateAction,\n\tInvalidOperationError,\n} from \"@commercetools/platform-sdk\";\nimport { CommercetoolsError } from \"#src/exceptions.ts\";\nimport { getStoreKeyReference } from \"#src/repositories/helpers.ts\";\nimport type { Writable } from \"#src/types.ts\";\nimport type { UpdateHandlerInterface } from \"../abstract.ts\";\nimport { AbstractUpdateHandler, type RepositoryContext } from \"../abstract.ts\";\n\nexport class CartDiscountUpdateHandler\n\textends AbstractUpdateHandler\n\timplements\n\t\tPartial<UpdateHandlerInterface<CartDiscount, CartDiscountUpdateAction>>\n{\n\tchangeIsActive(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<CartDiscount>,\n\t\t{ isActive }: CartDiscountChangeIsActiveAction,\n\t) {\n\t\tresource.isActive = isActive;\n\t}\n\n\tchangeSortOrder(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<CartDiscount>,\n\t\t{ sortOrder }: CartDiscountChangeSortOrderAction,\n\t) {\n\t\tresource.sortOrder = sortOrder;\n\t}\n\n\tchangeTarget(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<CartDiscount>,\n\t\t{ target }: CartDiscountChangeTargetAction,\n\t) {\n\t\tresource.target = target;\n\t}\n\n\tsetCustomField(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<CartDiscount>,\n\t\t{ name, value }: CartDiscountSetCustomFieldAction,\n\t) {\n\t\tif (!resource.custom) {\n\t\t\treturn;\n\t\t}\n\t\tif (value === null) {\n\t\t\tif (name in resource.custom.fields) {\n\t\t\t\tdelete resource.custom.fields[name];\n\t\t\t} else {\n\t\t\t\tthrow new CommercetoolsError<InvalidOperationError>(\n\t\t\t\t\t{\n\t\t\t\t\t\tcode: \"InvalidOperation\",\n\t\t\t\t\t\tmessage: `Cannot remove custom field ${name} because it does not exist.`,\n\t\t\t\t\t},\n\t\t\t\t\t400,\n\t\t\t\t);\n\t\t\t}\n\t\t} else {\n\t\t\tresource.custom.fields[name] = value;\n\t\t}\n\t}\n\n\tsetCustomType(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<CartDiscount>,\n\t\t{ type, fields }: CartDiscountSetCustomTypeAction,\n\t) {\n\t\tif (!type) {\n\t\t\tresource.custom = undefined;\n\t\t} else {\n\t\t\tconst resolvedType = this._storage.getByResourceIdentifier(\n\t\t\t\tcontext.projectKey,\n\t\t\t\ttype,\n\t\t\t);\n\t\t\tif (!resolvedType) {\n\t\t\t\tthrow new Error(`Type ${type} not found`);\n\t\t\t}\n\n\t\t\tresource.custom = {\n\t\t\t\ttype: {\n\t\t\t\t\ttypeId: \"type\",\n\t\t\t\t\tid: resolvedType.id,\n\t\t\t\t},\n\t\t\t\tfields: fields || {},\n\t\t\t};\n\t\t}\n\t}\n\n\tsetDescription(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<CartDiscount>,\n\t\t{ description }: CartDiscountSetDescriptionAction,\n\t) {\n\t\tresource.description = description;\n\t}\n\n\tsetKey(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<CartDiscount>,\n\t\t{ key }: CartDiscountSetKeyAction,\n\t) {\n\t\tresource.key = key;\n\t}\n\n\tsetStores(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<CartDiscount>,\n\t\t{ stores }: CartDiscountSetStoresAction,\n\t) {\n\t\tresource.stores = stores?.map((s) =>\n\t\t\tgetStoreKeyReference(s, context.projectKey, this._storage),\n\t\t);\n\t}\n\n\tsetValidFrom(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<CartDiscount>,\n\t\t{ validFrom }: CartDiscountSetValidFromAction,\n\t) {\n\t\tresource.validFrom = validFrom;\n\t}\n\n\tsetValidFromAndUntil(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<CartDiscount>,\n\t\t{ validFrom, validUntil }: CartDiscountSetValidFromAndUntilAction,\n\t) {\n\t\tresource.validFrom = validFrom;\n\t\tresource.validUntil = validUntil;\n\t}\n\n\tsetValidUntil(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<CartDiscount>,\n\t\t{ validUntil }: CartDiscountSetValidUntilAction,\n\t) {\n\t\tresource.validUntil = validUntil;\n\t}\n}\n","import type {\n\tCartDiscount,\n\tCartDiscountDraft,\n\tCartDiscountValueAbsolute,\n\tCartDiscountValueDraft,\n\tCartDiscountValueFixed,\n\tCartDiscountValueGiftLineItem,\n\tCartDiscountValueRelative,\n} from \"@commercetools/platform-sdk\";\nimport type { Config } from \"#src/config.ts\";\nimport { getBaseResourceProperties } from \"#src/helpers.ts\";\nimport {\n\tAbstractResourceRepository,\n\ttype RepositoryContext,\n} from \"../abstract.ts\";\nimport {\n\tcreateCustomFields,\n\tcreateTypedMoney,\n\tgetStoreKeyReference,\n} from \"../helpers.ts\";\nimport { CartDiscountUpdateHandler } from \"./actions.ts\";\n\nexport class CartDiscountRepository extends AbstractResourceRepository<\"cart-discount\"> {\n\tconstructor(config: Config) {\n\t\tsuper(\"cart-discount\", config);\n\t\tthis.actions = new CartDiscountUpdateHandler(config.storage);\n\t}\n\n\tcreate(context: RepositoryContext, draft: CartDiscountDraft): CartDiscount {\n\t\tconst resource: CartDiscount = {\n\t\t\t...getBaseResourceProperties(),\n\t\t\tkey: draft.key,\n\t\t\tdescription: draft.description,\n\t\t\tcartPredicate: draft.cartPredicate,\n\t\t\tisActive: draft.isActive || false,\n\t\t\tname: draft.name,\n\t\t\tstores:\n\t\t\t\tdraft.stores?.map((s) =>\n\t\t\t\t\tgetStoreKeyReference(s, context.projectKey, this._storage),\n\t\t\t\t) ?? [],\n\t\t\treferences: [],\n\t\t\ttarget: draft.target,\n\t\t\trequiresDiscountCode: draft.requiresDiscountCode || false,\n\t\t\tsortOrder: draft.sortOrder ?? \"0.1\",\n\t\t\tstackingMode: draft.stackingMode || \"Stacking\",\n\t\t\tvalidFrom: draft.validFrom,\n\t\t\tvalidUntil: draft.validUntil,\n\t\t\tvalue: this.transformValueDraft(draft.value),\n\t\t\tcustom: createCustomFields(\n\t\t\t\tdraft.custom,\n\t\t\t\tcontext.projectKey,\n\t\t\t\tthis._storage,\n\t\t\t),\n\t\t};\n\t\treturn this.saveNew(context, resource);\n\t}\n\n\tprivate transformValueDraft(value: CartDiscountValueDraft) {\n\t\tswitch (value.type) {\n\t\t\tcase \"absolute\": {\n\t\t\t\treturn {\n\t\t\t\t\ttype: \"absolute\",\n\t\t\t\t\tmoney: value.money.map(createTypedMoney),\n\t\t\t\t} as CartDiscountValueAbsolute;\n\t\t\t}\n\t\t\tcase \"fixed\": {\n\t\t\t\treturn {\n\t\t\t\t\ttype: \"fixed\",\n\t\t\t\t\tmoney: value.money.map(createTypedMoney),\n\t\t\t\t} as CartDiscountValueFixed;\n\t\t\t}\n\t\t\tcase \"giftLineItem\": {\n\t\t\t\treturn {\n\t\t\t\t\t...value,\n\t\t\t\t} as CartDiscountValueGiftLineItem;\n\t\t\t}\n\t\t\tcase \"relative\": {\n\t\t\t\treturn {\n\t\t\t\t\t...value,\n\t\t\t\t} as CartDiscountValueRelative;\n\t\t\t}\n\t\t}\n\t}\n}\n","/**\n * This module implements the reference expansion as imeplemented by\n * commercetools.\n *\n * See https://docs.commercetools.com/api/general-concepts#reference-expansion\n *\n * TODO: implement support for multi-dimensional array\n */\ntype ExpandResult = {\n\telement: string;\n\tindex?: string | number;\n\trest?: string;\n};\n\nexport const parseExpandClause = (clause: string): ExpandResult => {\n\tconst result: ExpandResult = {\n\t\telement: clause,\n\t\tindex: undefined,\n\t\trest: undefined,\n\t};\n\n\tconst pos = clause.indexOf(\".\");\n\tif (pos > 0) {\n\t\tresult.element = clause.substring(0, pos);\n\t\tresult.rest = clause.substring(pos + 1);\n\t}\n\n\tconst match = result.element.match(/\\[([^\\]+])]/);\n\tif (match) {\n\t\tresult.index = match[1] === \"*\" ? \"*\" : Number.parseInt(match[1], 10);\n\t\tresult.element = result.element.substring(0, match.index);\n\t}\n\treturn result;\n};\n","import type {\n\tAsset,\n\tAssetDraft,\n\tCategory,\n\tCategoryAddAssetAction,\n\tCategoryChangeAssetNameAction,\n\tCategoryChangeNameAction,\n\tCategoryChangeParentAction,\n\tCategoryChangeSlugAction,\n\tCategoryRemoveAssetAction,\n\tCategorySetAssetDescriptionAction,\n\tCategorySetAssetSourcesAction,\n\tCategorySetCustomFieldAction,\n\tCategorySetCustomTypeAction,\n\tCategorySetDescriptionAction,\n\tCategorySetKeyAction,\n\tCategorySetMetaDescriptionAction,\n\tCategorySetMetaKeywordsAction,\n\tCategorySetMetaTitleAction,\n\tCategoryUpdateAction,\n} from \"@commercetools/platform-sdk\";\nimport { v4 as uuidv4 } from \"uuid\";\nimport type { Writable } from \"#src/types.ts\";\nimport type { RepositoryContext, UpdateHandlerInterface } from \"../abstract.ts\";\nimport { AbstractUpdateHandler } from \"../abstract.ts\";\nimport { createCustomFields } from \"../helpers.ts\";\n\nexport class CategoryUpdateHandler\n\textends AbstractUpdateHandler\n\timplements Partial<UpdateHandlerInterface<Category, CategoryUpdateAction>>\n{\n\taddAsset(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Category>,\n\t\t{ asset }: CategoryAddAssetAction,\n\t) {\n\t\tif (!resource.assets) {\n\t\t\tresource.assets = [this.assetFromAssetDraft(asset, context)];\n\t\t} else {\n\t\t\tresource.assets.push(this.assetFromAssetDraft(asset, context));\n\t\t}\n\t}\n\n\tchangeAssetName(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Category>,\n\t\t{ assetId, assetKey, name }: CategoryChangeAssetNameAction,\n\t) {\n\t\tresource.assets?.forEach((asset) => {\n\t\t\tif (assetId && assetId === asset.id) {\n\t\t\t\tasset.name = name;\n\t\t\t}\n\t\t\tif (assetKey && assetKey === asset.key) {\n\t\t\t\tasset.name = name;\n\t\t\t}\n\t\t});\n\t}\n\n\tchangeName(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Category>,\n\t\t{ name }: CategoryChangeNameAction,\n\t) {\n\t\tresource.name = name;\n\t}\n\n\tchangeParent(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Category>,\n\t\t{ parent }: CategoryChangeParentAction,\n\t) {\n\t\tconst category = this._storage.getByResourceIdentifier(\n\t\t\tcontext.projectKey,\n\t\t\tparent,\n\t\t);\n\t\tif (!category) {\n\t\t\tthrow new Error(\"No category found for reference\");\n\t\t}\n\t\tresource.parent = {\n\t\t\ttypeId: \"category\",\n\t\t\tid: category.id,\n\t\t};\n\t}\n\n\tchangeSlug(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Category>,\n\t\t{ slug }: CategoryChangeSlugAction,\n\t) {\n\t\tresource.slug = slug;\n\t}\n\n\tremoveAsset(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Category>,\n\t\t{ assetId, assetKey }: CategoryRemoveAssetAction,\n\t) {\n\t\tif (!resource.assets) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (assetId) {\n\t\t\tresource.assets = resource.assets.filter((obj) => obj.id !== assetId);\n\n\t\t\treturn;\n\t\t}\n\n\t\tif (assetKey) {\n\t\t\tresource.assets = resource.assets.filter((obj) => obj.key !== assetKey);\n\n\t\t\treturn;\n\t\t}\n\t}\n\n\tsetAssetDescription(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Category>,\n\t\t{ assetId, assetKey, description }: CategorySetAssetDescriptionAction,\n\t) {\n\t\tresource.assets?.forEach((asset) => {\n\t\t\tif (assetId && assetId === asset.id) {\n\t\t\t\tasset.description = description;\n\t\t\t}\n\t\t\tif (assetKey && assetKey === asset.key) {\n\t\t\t\tasset.description = description;\n\t\t\t}\n\t\t});\n\t}\n\n\tsetAssetSources(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Category>,\n\t\t{ assetId, assetKey, sources }: CategorySetAssetSourcesAction,\n\t) {\n\t\tresource.assets?.forEach((asset) => {\n\t\t\tif (assetId && assetId === asset.id) {\n\t\t\t\tasset.sources = sources;\n\t\t\t}\n\t\t\tif (assetKey && assetKey === asset.key) {\n\t\t\t\tasset.sources = sources;\n\t\t\t}\n\t\t});\n\t}\n\n\tsetCustomField(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Category>,\n\t\t{ name, value }: CategorySetCustomFieldAction,\n\t) {\n\t\tif (!resource.custom) {\n\t\t\treturn;\n\t\t}\n\t\tif (value === null) {\n\t\t\tdelete resource.custom.fields[name];\n\t\t} else {\n\t\t\tresource.custom.fields[name] = value;\n\t\t}\n\t}\n\n\tsetCustomType(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Category>,\n\t\t{ type, fields }: CategorySetCustomTypeAction,\n\t) {\n\t\tif (type) {\n\t\t\tresource.custom = createCustomFields(\n\t\t\t\t{ type, fields },\n\t\t\t\tcontext.projectKey,\n\t\t\t\tthis._storage,\n\t\t\t);\n\t\t} else {\n\t\t\tresource.custom = undefined;\n\t\t}\n\t}\n\n\tsetDescription(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Category>,\n\t\t{ description }: CategorySetDescriptionAction,\n\t) {\n\t\tresource.description = description;\n\t}\n\n\tsetKey(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Category>,\n\t\t{ key }: CategorySetKeyAction,\n\t) {\n\t\tresource.key = key;\n\t}\n\n\tsetMetaDescription(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Category>,\n\t\t{ metaDescription }: CategorySetMetaDescriptionAction,\n\t) {\n\t\tresource.metaDescription = metaDescription;\n\t}\n\n\tsetMetaKeywords(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Category>,\n\t\t{ metaKeywords }: CategorySetMetaKeywordsAction,\n\t) {\n\t\tresource.metaKeywords = metaKeywords;\n\t}\n\n\tsetMetaTitle(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Category>,\n\t\t{ metaTitle }: CategorySetMetaTitleAction,\n\t) {\n\t\tresource.metaTitle = metaTitle;\n\t}\n\n\tassetFromAssetDraft = (\n\t\tdraft: AssetDraft,\n\t\tcontext: RepositoryContext,\n\t): Asset => ({\n\t\t...draft,\n\t\tid: uuidv4(),\n\t\tcustom: createCustomFields(draft.custom, context.projectKey, this._storage),\n\t});\n}\n","import type {\n\tCategory,\n\tCategoryDraft,\n\tCategoryReference,\n} from \"@commercetools/platform-sdk\";\nimport { v4 as uuidv4 } from \"uuid\";\nimport type { Config } from \"#src/config.ts\";\nimport { getBaseResourceProperties } from \"#src/helpers.ts\";\nimport { parseExpandClause } from \"#src/lib/expandParser.ts\";\nimport type { Writable } from \"#src/types.ts\";\nimport type { GetParams } from \"../abstract.ts\";\nimport {\n\tAbstractResourceRepository,\n\ttype RepositoryContext,\n} from \"../abstract.ts\";\nimport { createCustomFields } from \"../helpers.ts\";\nimport { CategoryUpdateHandler } from \"./actions.ts\";\n\nexport class CategoryRepository extends AbstractResourceRepository<\"category\"> {\n\tconstructor(config: Config) {\n\t\tsuper(\"category\", config);\n\t\tthis.actions = new CategoryUpdateHandler(this._storage);\n\t}\n\n\tcreate(context: RepositoryContext, draft: CategoryDraft): Category {\n\t\tconst resource: Category = {\n\t\t\t...getBaseResourceProperties(),\n\t\t\tkey: draft.key,\n\t\t\tname: draft.name,\n\t\t\tslug: draft.slug,\n\t\t\tdescription: draft.description,\n\t\t\tmetaDescription: draft.metaDescription,\n\t\t\tmetaKeywords: draft.metaKeywords,\n\t\t\torderHint: draft.orderHint || \"\",\n\t\t\texternalId: draft.externalId || \"\",\n\t\t\tparent: draft.parent\n\t\t\t\t? { typeId: \"category\", id: draft.parent.id! }\n\t\t\t\t: undefined,\n\t\t\tancestors: [], // Resolved at runtime\n\t\t\tassets:\n\t\t\t\tdraft.assets?.map((d) => ({\n\t\t\t\t\tid: uuidv4(),\n\t\t\t\t\tname: d.name,\n\t\t\t\t\tdescription: d.description,\n\t\t\t\t\tsources: d.sources,\n\t\t\t\t\ttags: d.tags,\n\t\t\t\t\tkey: d.key,\n\t\t\t\t\tcustom: createCustomFields(\n\t\t\t\t\t\tdraft.custom,\n\t\t\t\t\t\tcontext.projectKey,\n\t\t\t\t\t\tthis._storage,\n\t\t\t\t\t),\n\t\t\t\t})) || [],\n\t\t\tcustom: createCustomFields(\n\t\t\t\tdraft.custom,\n\t\t\t\tcontext.projectKey,\n\t\t\t\tthis._storage,\n\t\t\t),\n\t\t};\n\t\treturn this.saveNew(context, resource);\n\t}\n\n\tpostProcessResource(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Category>,\n\t\tparams?: GetParams,\n\t): Category {\n\t\tlet node: Category = resource;\n\t\tconst ancestors: CategoryReference[] = [];\n\n\t\t// TODO: The expand clause here is a hack, the current expand architecture\n\t\t// is not able to handle the case for 'dynamic' fields like ancestors which\n\t\t// are resolved at runtime. We should do the expand resolution post query\n\t\t// execution for all resources\n\n\t\tconst expandClauses = params?.expand?.map(parseExpandClause) ?? [];\n\t\tconst addExpand = expandClauses?.find(\n\t\t\t(c) => c.element === \"ancestors\" && c.index === \"*\",\n\t\t);\n\n\t\twhile (node.parent) {\n\t\t\tnode = this._storage.getByResourceIdentifier<\"category\">(\n\t\t\t\tcontext.projectKey,\n\t\t\t\tnode.parent,\n\t\t\t);\n\t\t\tancestors.push({\n\t\t\t\ttypeId: \"category\",\n\t\t\t\tid: node.id,\n\t\t\t\tobj: addExpand ? node : undefined,\n\t\t\t});\n\t\t}\n\n\t\tresource.ancestors = ancestors;\n\t\treturn resource;\n\t}\n}\n","import type {\n\tChannel,\n\tChannelChangeDescriptionAction,\n\tChannelChangeKeyAction,\n\tChannelChangeNameAction,\n\tChannelDraft,\n\tChannelSetAddressAction,\n\tChannelSetCustomFieldAction,\n\tChannelSetCustomTypeAction,\n\tChannelSetGeoLocationAction,\n\tChannelUpdateAction,\n} from \"@commercetools/platform-sdk\";\nimport type { Config } from \"#src/config.ts\";\nimport { getBaseResourceProperties } from \"../helpers.ts\";\nimport type { Writable } from \"../types.ts\";\nimport type { UpdateHandlerInterface } from \"./abstract.ts\";\nimport {\n\tAbstractResourceRepository,\n\tAbstractUpdateHandler,\n\ttype RepositoryContext,\n} from \"./abstract.ts\";\nimport { createAddress, createCustomFields } from \"./helpers.ts\";\n\nexport class ChannelRepository extends AbstractResourceRepository<\"channel\"> {\n\tconstructor(config: Config) {\n\t\tsuper(\"channel\", config);\n\t\tthis.actions = new ChannelUpdateHandler(this._storage);\n\t}\n\n\tcreate(context: RepositoryContext, draft: ChannelDraft): Channel {\n\t\tconst resource: Channel = {\n\t\t\t...getBaseResourceProperties(),\n\t\t\tkey: draft.key,\n\t\t\tname: draft.name,\n\t\t\tdescription: draft.description,\n\t\t\troles: draft.roles || [],\n\t\t\tgeoLocation: draft.geoLocation,\n\t\t\taddress: createAddress(draft.address, context.projectKey, this._storage),\n\t\t\tcustom: createCustomFields(\n\t\t\t\tdraft.custom,\n\t\t\t\tcontext.projectKey,\n\t\t\t\tthis._storage,\n\t\t\t),\n\t\t};\n\t\treturn this.saveNew(context, resource);\n\t}\n}\n\nclass ChannelUpdateHandler\n\textends AbstractUpdateHandler\n\timplements Partial<UpdateHandlerInterface<Channel, ChannelUpdateAction>>\n{\n\tchangeDescription(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Channel>,\n\t\t{ description }: ChannelChangeDescriptionAction,\n\t) {\n\t\tresource.description = description;\n\t}\n\n\tchangeKey(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Channel>,\n\t\t{ key }: ChannelChangeKeyAction,\n\t) {\n\t\tresource.key = key;\n\t}\n\n\tchangeName(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Channel>,\n\t\t{ name }: ChannelChangeNameAction,\n\t) {\n\t\tresource.name = name;\n\t}\n\n\tsetAddress(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Channel>,\n\t\t{ address }: ChannelSetAddressAction,\n\t) {\n\t\tresource.address = createAddress(\n\t\t\taddress,\n\t\t\tcontext.projectKey,\n\t\t\tthis._storage,\n\t\t);\n\t}\n\n\tsetCustomField(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Channel>,\n\t\t{ name, value }: ChannelSetCustomFieldAction,\n\t) {\n\t\tif (!resource.custom) {\n\t\t\treturn;\n\t\t}\n\t\tif (value === null) {\n\t\t\tdelete resource.custom.fields[name];\n\t\t} else {\n\t\t\tresource.custom.fields[name] = value;\n\t\t}\n\t}\n\n\tsetCustomType(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Channel>,\n\t\t{ type, fields }: ChannelSetCustomTypeAction,\n\t) {\n\t\tif (type) {\n\t\t\tresource.custom = createCustomFields(\n\t\t\t\t{ type, fields },\n\t\t\t\tcontext.projectKey,\n\t\t\t\tthis._storage,\n\t\t\t);\n\t\t} else {\n\t\t\tresource.custom = undefined;\n\t\t}\n\t}\n\n\tsetGeoLocation(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Channel>,\n\t\t{ geoLocation }: ChannelSetGeoLocationAction,\n\t) {\n\t\tresource.geoLocation = geoLocation;\n\t}\n}\n","import type {\n\tCustomObject,\n\tCustomObjectDraft,\n\tInvalidOperationError,\n} from \"@commercetools/platform-sdk\";\nimport type { Config } from \"#src/config.ts\";\nimport { CommercetoolsError } from \"#src/exceptions.ts\";\nimport { cloneObject, getBaseResourceProperties } from \"../helpers.ts\";\nimport type { Writable } from \"../types.ts\";\nimport type { QueryParams } from \"./abstract.ts\";\nimport {\n\tAbstractResourceRepository,\n\ttype RepositoryContext,\n} from \"./abstract.ts\";\nimport { checkConcurrentModification } from \"./errors.ts\";\n\nexport class CustomObjectRepository extends AbstractResourceRepository<\"key-value-document\"> {\n\tconstructor(config: Config) {\n\t\tsuper(\"key-value-document\", config);\n\t}\n\n\tcreate(\n\t\tcontext: RepositoryContext,\n\t\tdraft: Writable<CustomObjectDraft>,\n\t): CustomObject {\n\t\tconst current = this.getWithContainerAndKey(\n\t\t\tcontext,\n\t\t\tdraft.container,\n\t\t\tdraft.key,\n\t\t) as Writable<CustomObject | undefined>;\n\n\t\tif (current) {\n\t\t\t// Only check version if it is passed in the draft\n\t\t\tif (draft.version) {\n\t\t\t\tcheckConcurrentModification(current.version, draft.version, current.id);\n\t\t\t} else {\n\t\t\t\tdraft.version = current.version;\n\t\t\t}\n\n\t\t\tif (draft.value !== current.value) {\n\t\t\t\tconst updated = cloneObject(current) as Writable<CustomObject>;\n\t\t\t\tupdated.value = draft.value;\n\t\t\t\tupdated.version += 1;\n\t\t\t\tthis.saveUpdate(context, draft.version, updated);\n\t\t\t\treturn updated;\n\t\t\t}\n\t\t\treturn current;\n\t\t}\n\t\t// If the resource is new the only valid version is 0\n\t\tif (draft.version) {\n\t\t\tthrow new CommercetoolsError<InvalidOperationError>(\n\t\t\t\t{\n\t\t\t\t\tcode: \"InvalidOperation\",\n\t\t\t\t\tmessage: \"version on create must be 0\",\n\t\t\t\t},\n\t\t\t\t400,\n\t\t\t);\n\t\t}\n\t\tconst baseProperties = getBaseResourceProperties();\n\t\tconst resource: CustomObject = {\n\t\t\t...baseProperties,\n\t\t\tcontainer: draft.container,\n\t\t\tkey: draft.key,\n\t\t\tvalue: draft.value,\n\t\t};\n\n\t\tthis.saveNew(context, resource);\n\t\treturn resource;\n\t}\n\n\tgetWithContainerAndKey(\n\t\tcontext: RepositoryContext,\n\t\tcontainer: string,\n\t\tkey: string,\n\t) {\n\t\tconst items = this._storage.all(context.projectKey, this.getTypeId());\n\t\treturn items.find(\n\t\t\t(item) => item.container === container && item.key === key,\n\t\t);\n\t}\n\n\tqueryWithContainer(\n\t\tcontext: RepositoryContext,\n\t\tcontainer: string,\n\t\tparams: QueryParams = {},\n\t) {\n\t\tconst whereClause = params.where || [];\n\t\twhereClause.push(`container=\"${container}\"`);\n\t\tconst result = this._storage.query(context.projectKey, this.getTypeId(), {\n\t\t\t...params,\n\t\t\twhere: whereClause,\n\t\t});\n\n\t\t// @ts-expect-error\n\t\tresult.results = result.results.map((r) =>\n\t\t\tthis.postProcessResource(context, r as CustomObject, {\n\t\t\t\texpand: params.expand,\n\t\t\t}),\n\t\t);\n\t\treturn result;\n\t}\n}\n","import assert from \"node:assert\";\nimport type {\n\tAddress,\n\tBaseAddress,\n\tCustomer,\n\tCustomerAddAddressAction,\n\tCustomerAddBillingAddressIdAction,\n\tCustomerAddShippingAddressIdAction,\n\tCustomerAddStoreAction,\n\tCustomerChangeAddressAction,\n\tCustomerChangeEmailAction,\n\tCustomerRemoveAddressAction,\n\tCustomerRemoveBillingAddressIdAction,\n\tCustomerRemoveShippingAddressIdAction,\n\tCustomerRemoveStoreAction,\n\tCustomerSetAddressCustomFieldAction,\n\tCustomerSetAddressCustomTypeAction,\n\tCustomerSetAuthenticationModeAction,\n\tCustomerSetCompanyNameAction,\n\tCustomerSetCustomerGroupAction,\n\tCustomerSetCustomerNumberAction,\n\tCustomerSetCustomFieldAction,\n\tCustomerSetCustomTypeAction,\n\tCustomerSetDateOfBirthAction,\n\tCustomerSetDefaultBillingAddressAction,\n\tCustomerSetDefaultShippingAddressAction,\n\tCustomerSetExternalIdAction,\n\tCustomerSetFirstNameAction,\n\tCustomerSetKeyAction,\n\tCustomerSetLastNameAction,\n\tCustomerSetLocaleAction,\n\tCustomerSetMiddleNameAction,\n\tCustomerSetSalutationAction,\n\tCustomerSetStoresAction,\n\tCustomerSetTitleAction,\n\tCustomerSetVatIdAction,\n\tCustomerUpdateAction,\n\tInvalidInputError,\n\tInvalidJsonInputError,\n\tInvalidOperationError,\n} from \"@commercetools/platform-sdk\";\nimport { CommercetoolsError } from \"#src/exceptions.ts\";\nimport { generateRandomString } from \"#src/helpers.ts\";\nimport { hashPassword } from \"#src/lib/password.ts\";\nimport type { Writable } from \"#src/types.ts\";\nimport type { UpdateHandlerInterface } from \"../abstract.ts\";\nimport { AbstractUpdateHandler, type RepositoryContext } from \"../abstract.ts\";\nimport { createAddress, createCustomFields } from \"../helpers.ts\";\n\nexport class CustomerUpdateHandler\n\textends AbstractUpdateHandler\n\timplements Partial<UpdateHandlerInterface<Customer, CustomerUpdateAction>>\n{\n\taddAddress(\n\t\t_context: RepositoryContext,\n\t\tresource: Writable<Customer>,\n\t\t{ address }: CustomerAddAddressAction,\n\t) {\n\t\tresource.addresses.push({\n\t\t\t...address,\n\t\t\tid: address.id ?? generateRandomString(5),\n\t\t} as BaseAddress);\n\t}\n\n\taddBillingAddressId(\n\t\t_context: RepositoryContext,\n\t\tresource: Writable<Customer>,\n\t\t{ addressId, addressKey }: CustomerAddBillingAddressIdAction,\n\t) {\n\t\tconst address = this._findAddress(resource, addressId, addressKey, true);\n\t\tassert(address?.id); // always true since we set required to true\n\n\t\tif (resource.billingAddressIds === undefined) {\n\t\t\tresource.billingAddressIds = [];\n\t\t}\n\n\t\tif (!resource.billingAddressIds.includes(address.id)) {\n\t\t\tresource.billingAddressIds.push(address.id);\n\t\t}\n\t}\n\n\taddShippingAddressId(\n\t\t_context: RepositoryContext,\n\t\tresource: Writable<Customer>,\n\t\t{ addressId, addressKey }: CustomerAddShippingAddressIdAction,\n\t) {\n\t\tconst address = this._findAddress(resource, addressId, addressKey, true);\n\t\tassert(address?.id); // always true since we set required to true\n\n\t\tif (resource.shippingAddressIds === undefined) {\n\t\t\tresource.shippingAddressIds = [];\n\t\t}\n\n\t\tif (!resource.shippingAddressIds.includes(address.id)) {\n\t\t\tresource.shippingAddressIds.push(address.id);\n\t\t}\n\t\treturn resource;\n\t}\n\n\taddStore(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Customer>,\n\t\taction: CustomerAddStoreAction,\n\t) {\n\t\tthrow new Error(\"Method not implemented.\");\n\t}\n\n\tchangeAddress(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Customer>,\n\t\t{ addressId, addressKey, address }: CustomerChangeAddressAction,\n\t) {\n\t\tconst current = this._findAddress(resource, addressId, addressKey, true);\n\t\tassert(current?.id); // always true since we set required to true\n\n\t\tconst oldAddressIndex = resource.addresses.findIndex(\n\t\t\t(a) => a.id === current.id,\n\t\t);\n\n\t\tconst newAddress = createAddress(\n\t\t\taddress,\n\t\t\tcontext.projectKey,\n\t\t\tthis._storage,\n\t\t);\n\n\t\tif (newAddress) {\n\t\t\tresource.addresses[oldAddressIndex] = {\n\t\t\t\tid: addressId,\n\t\t\t\t...newAddress,\n\t\t\t};\n\t\t}\n\t}\n\n\tchangeEmail(\n\t\t_context: RepositoryContext,\n\t\tresource: Writable<Customer>,\n\t\t{ email }: CustomerChangeEmailAction,\n\t) {\n\t\tresource.email = email;\n\t}\n\n\tremoveAddress(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Customer>,\n\t\taction: CustomerRemoveAddressAction,\n\t) {\n\t\tconst address = this._findAddress(\n\t\t\tresource,\n\t\t\taction.addressId,\n\t\t\taction.addressKey,\n\t\t\ttrue,\n\t\t);\n\t\tassert(address?.id); // always true since we set required to true\n\t\tresource.addresses = resource.addresses.filter((a) => a.id !== address.id);\n\t}\n\n\tremoveBillingAddressId(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Customer>,\n\t\taction: CustomerRemoveBillingAddressIdAction,\n\t) {\n\t\tconst address = this._findAddress(\n\t\t\tresource,\n\t\t\taction.addressId,\n\t\t\taction.addressKey,\n\t\t\ttrue,\n\t\t);\n\t\tassert(address?.id); // always true since we set required to true\n\t\tresource.billingAddressIds = resource.billingAddressIds?.filter(\n\t\t\t(id) => id !== address.id,\n\t\t);\n\t\tif (resource.defaultBillingAddressId === address.id) {\n\t\t\tresource.defaultBillingAddressId = undefined;\n\t\t}\n\t}\n\n\tremoveShippingAddressId(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Customer>,\n\t\taction: CustomerRemoveShippingAddressIdAction,\n\t) {\n\t\tconst address = this._findAddress(\n\t\t\tresource,\n\t\t\taction.addressId,\n\t\t\taction.addressKey,\n\t\t\ttrue,\n\t\t);\n\t\tassert(address?.id); // always true since we set required to true\n\t\tresource.shippingAddressIds = resource.shippingAddressIds?.filter(\n\t\t\t(id) => id !== address.id,\n\t\t);\n\t\tif (resource.defaultShippingAddressId === address.id) {\n\t\t\tresource.defaultShippingAddressId = undefined;\n\t\t}\n\t}\n\n\tremoveStore(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Customer>,\n\t\taction: CustomerRemoveStoreAction,\n\t) {\n\t\tthrow new Error(\"Method not implemented.\");\n\t}\n\n\tsetAddressCustomField(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Customer>,\n\t\taction: CustomerSetAddressCustomFieldAction,\n\t) {\n\t\tthrow new Error(\"Method not implemented.\");\n\t}\n\n\tsetAddressCustomType(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Customer>,\n\t\taction: CustomerSetAddressCustomTypeAction,\n\t) {\n\t\tthrow new Error(\"Method not implemented.\");\n\t}\n\n\tsetAuthenticationMode(\n\t\t_context: RepositoryContext,\n\t\tresource: Writable<Customer>,\n\t\t{ authMode, password }: CustomerSetAuthenticationModeAction,\n\t) {\n\t\tif (resource.authenticationMode === authMode) {\n\t\t\tthrow new CommercetoolsError<InvalidInputError>(\n\t\t\t\t{\n\t\t\t\t\tcode: \"InvalidInput\",\n\t\t\t\t\tmessage: `The customer is already using the '${resource.authenticationMode}' authentication mode.`,\n\t\t\t\t},\n\t\t\t\t400,\n\t\t\t);\n\t\t}\n\t\tresource.authenticationMode = authMode;\n\t\tif (authMode === \"ExternalAuth\") {\n\t\t\tresource.password = undefined;\n\t\t\treturn;\n\t\t}\n\t\tif (authMode === \"Password\") {\n\t\t\tresource.password = password ? hashPassword(password) : undefined;\n\t\t\treturn;\n\t\t}\n\t\tthrow new CommercetoolsError<InvalidJsonInputError>(\n\t\t\t{\n\t\t\t\tcode: \"InvalidJsonInput\",\n\t\t\t\tmessage: \"Request body does not contain valid JSON.\",\n\t\t\t\tdetailedErrorMessage: `actions -> authMode: Invalid enum value: '${authMode}'. Expected one of: 'Password','ExternalAuth'`,\n\t\t\t},\n\t\t\t400,\n\t\t);\n\t}\n\n\tsetCompanyName(\n\t\t_context: RepositoryContext,\n\t\tresource: Writable<Customer>,\n\t\t{ companyName }: CustomerSetCompanyNameAction,\n\t) {\n\t\tresource.companyName = companyName;\n\t}\n\n\tsetCustomerGroup(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Customer>,\n\t\taction: CustomerSetCustomerGroupAction,\n\t) {\n\t\tif (!action.customerGroup) {\n\t\t\tthrow new CommercetoolsError<InvalidOperationError>(\n\t\t\t\t{\n\t\t\t\t\tcode: \"InvalidOperation\",\n\t\t\t\t\tmessage: \"CustomerGroup is required.\",\n\t\t\t\t},\n\t\t\t\t400,\n\t\t\t);\n\t\t}\n\n\t\tconst group = this._storage.getByResourceIdentifier<\"customer-group\">(\n\t\t\tcontext.projectKey,\n\t\t\taction.customerGroup,\n\t\t);\n\n\t\tresource.customerGroup = {\n\t\t\ttypeId: \"customer-group\",\n\t\t\tid: group.id,\n\t\t};\n\t}\n\n\tsetCustomerNumber(\n\t\t_context: RepositoryContext,\n\t\tresource: Writable<Customer>,\n\t\t{ customerNumber }: CustomerSetCustomerNumberAction,\n\t) {\n\t\tif (resource.customerNumber) {\n\t\t\tthrow new Error(\n\t\t\t\t\"A Customer number already exists and cannot be set again.\",\n\t\t\t);\n\t\t}\n\t\tresource.customerNumber = customerNumber;\n\t}\n\n\tsetCustomField(\n\t\t_context: RepositoryContext,\n\t\tresource: Writable<Customer>,\n\t\t{ name, value }: CustomerSetCustomFieldAction,\n\t) {\n\t\tif (!resource.custom) {\n\t\t\tthrow new Error(\"Resource has no custom field\");\n\t\t}\n\t\tresource.custom.fields[name] = value;\n\t}\n\n\tsetCustomType(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Customer>,\n\t\t{ type, fields }: CustomerSetCustomTypeAction,\n\t) {\n\t\tif (type) {\n\t\t\tresource.custom = createCustomFields(\n\t\t\t\t{ type, fields },\n\t\t\t\tcontext.projectKey,\n\t\t\t\tthis._storage,\n\t\t\t);\n\t\t} else {\n\t\t\tresource.custom = undefined;\n\t\t}\n\t}\n\n\tsetDateOfBirth(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Customer>,\n\t\taction: CustomerSetDateOfBirthAction,\n\t) {\n\t\tresource.dateOfBirth = action.dateOfBirth;\n\t}\n\n\tsetDefaultBillingAddress(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Customer>,\n\t\taction: CustomerSetDefaultBillingAddressAction,\n\t) {\n\t\tconst address = this._findAddress(\n\t\t\tresource,\n\t\t\taction.addressId,\n\t\t\taction.addressKey,\n\t\t\ttrue,\n\t\t);\n\t\tassert(address?.id); // always true since we set required to true\n\n\t\tresource.defaultBillingAddressId = address.id;\n\t\tif (resource.billingAddressIds === undefined) {\n\t\t\tresource.billingAddressIds = [];\n\t\t}\n\t\tif (!resource.billingAddressIds.includes(address.id)) {\n\t\t\tresource.billingAddressIds.push(address.id);\n\t\t}\n\t}\n\n\tsetDefaultShippingAddress(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Customer>,\n\t\taction: CustomerSetDefaultShippingAddressAction,\n\t) {\n\t\tconst address = this._findAddress(\n\t\t\tresource,\n\t\t\taction.addressId,\n\t\t\taction.addressKey,\n\t\t\ttrue,\n\t\t);\n\t\tassert(address?.id); // always true since we set required to true\n\n\t\tresource.defaultShippingAddressId = address.id;\n\t\tif (resource.shippingAddressIds === undefined) {\n\t\t\tresource.shippingAddressIds = [];\n\t\t}\n\t\tif (!resource.shippingAddressIds.includes(address.id)) {\n\t\t\tresource.shippingAddressIds.push(address.id);\n\t\t}\n\t}\n\n\tsetExternalId(\n\t\t_context: RepositoryContext,\n\t\tresource: Writable<Customer>,\n\t\t{ externalId }: CustomerSetExternalIdAction,\n\t) {\n\t\tresource.externalId = externalId;\n\t}\n\n\tsetFirstName(\n\t\t_context: RepositoryContext,\n\t\tresource: Writable<Customer>,\n\t\t{ firstName }: CustomerSetFirstNameAction,\n\t) {\n\t\tresource.firstName = firstName;\n\t}\n\n\tsetKey(\n\t\t_context: RepositoryContext,\n\t\tresource: Writable<Customer>,\n\t\t{ key }: CustomerSetKeyAction,\n\t) {\n\t\tresource.key = key;\n\t}\n\n\tsetLastName(\n\t\t_context: RepositoryContext,\n\t\tresource: Writable<Customer>,\n\t\t{ lastName }: CustomerSetLastNameAction,\n\t) {\n\t\tresource.lastName = lastName;\n\t}\n\n\tsetLocale(\n\t\t_context: RepositoryContext,\n\t\tresource: Writable<Customer>,\n\t\t{ locale }: CustomerSetLocaleAction,\n\t) {\n\t\tresource.locale = locale;\n\t}\n\n\tsetMiddleName(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Customer>,\n\t\taction: CustomerSetMiddleNameAction,\n\t) {\n\t\tresource.middleName = action.middleName;\n\t}\n\n\tsetSalutation(\n\t\t_context: RepositoryContext,\n\t\tresource: Writable<Customer>,\n\t\t{ salutation }: CustomerSetSalutationAction,\n\t) {\n\t\tresource.salutation = salutation;\n\t}\n\n\tsetStores(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Customer>,\n\t\taction: CustomerSetStoresAction,\n\t) {\n\t\tthrow new Error(\"Method not implemented.\");\n\t}\n\n\tsetTitle(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Customer>,\n\t\taction: CustomerSetTitleAction,\n\t) {\n\t\tresource.title = action.title;\n\t}\n\n\tsetVatId(\n\t\t_context: RepositoryContext,\n\t\tresource: Writable<Customer>,\n\t\t{ vatId }: CustomerSetVatIdAction,\n\t) {\n\t\tresource.vatId = vatId;\n\t}\n\n\tprivate _findAddress(\n\t\tresource: Writable<Customer>,\n\t\taddressId: string | undefined,\n\t\taddressKey: string | undefined,\n\t\trequired = false,\n\t): Address | undefined {\n\t\tif (addressKey) {\n\t\t\tconst address = resource.addresses.find((a) => a.key === addressKey);\n\t\t\tif (!address) {\n\t\t\t\tthrow new CommercetoolsError<InvalidOperationError>(\n\t\t\t\t\t{\n\t\t\t\t\t\tcode: \"InvalidOperation\",\n\t\t\t\t\t\tmessage: `Customer does not contain an address with the key ${addressKey}.`,\n\t\t\t\t\t},\n\t\t\t\t\t400,\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn address;\n\t\t}\n\n\t\tif (addressId) {\n\t\t\tconst address = resource.addresses.find((a) => a.id === addressId);\n\t\t\tif (!address) {\n\t\t\t\tthrow new CommercetoolsError<InvalidOperationError>(\n\t\t\t\t\t{\n\t\t\t\t\t\tcode: \"InvalidOperation\",\n\t\t\t\t\t\tmessage: `Customer does not contain an address with the id ${addressId}.`,\n\t\t\t\t\t},\n\t\t\t\t\t400,\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn address;\n\t\t}\n\n\t\tif (required) {\n\t\t\tthrow new CommercetoolsError<InvalidOperationError>(\n\t\t\t\t{\n\t\t\t\t\tcode: \"InvalidOperation\",\n\t\t\t\t\tmessage: \"One of address 'addressId' or 'addressKey' is required.\",\n\t\t\t\t},\n\t\t\t\t400,\n\t\t\t);\n\t\t}\n\t}\n}\n","import type {\n\tAddress,\n\tCustomer,\n\tCustomerCreatePasswordResetToken,\n\tCustomerDraft,\n\tCustomerResetPassword,\n\tCustomerToken,\n\tDuplicateFieldError,\n\tInvalidInputError,\n\tMyCustomerResetPassword,\n\tResourceNotFoundError,\n\tStore,\n\tStoreKeyReference,\n\tStoreResourceIdentifier,\n} from \"@commercetools/platform-sdk\";\nimport type { Config } from \"#src/config.ts\";\nimport { CommercetoolsError } from \"#src/exceptions.ts\";\nimport {\n\tgenerateRandomString,\n\tgetBaseResourceProperties,\n} from \"#src/helpers.ts\";\nimport {\n\tcreateEmailVerifyToken,\n\tcreatePasswordResetToken,\n\thashPassword,\n\tvalidatePasswordResetToken,\n} from \"#src/lib/password.ts\";\nimport type { ResourceMap, ShallowWritable, Writable } from \"#src/types.ts\";\nimport {\n\tAbstractResourceRepository,\n\ttype RepositoryContext,\n} from \"../abstract.ts\";\nimport { createCustomFields } from \"../helpers.ts\";\nimport { CustomerUpdateHandler } from \"./actions.ts\";\n\nexport class CustomerRepository extends AbstractResourceRepository<\"customer\"> {\n\tconstructor(config: Config) {\n\t\tsuper(\"customer\", config);\n\t\tthis.actions = new CustomerUpdateHandler(config.storage);\n\t}\n\n\tcreate(context: RepositoryContext, draft: CustomerDraft): Customer {\n\t\t// Check uniqueness\n\t\tconst results = this._storage.query(context.projectKey, this.getTypeId(), {\n\t\t\twhere: [`lowercaseEmail=\"${draft.email.toLowerCase()}\"`],\n\t\t});\n\t\tif (results.count > 0) {\n\t\t\tthrow new CommercetoolsError<any>({\n\t\t\t\tcode: \"CustomerAlreadyExists\",\n\t\t\t\tstatusCode: 400,\n\t\t\t\tmessage:\n\t\t\t\t\t\"There is already an existing customer with the provided email.\",\n\t\t\t\terrors: [\n\t\t\t\t\t{\n\t\t\t\t\t\tcode: \"DuplicateField\",\n\t\t\t\t\t\tmessage: `Customer with email '${draft.email}' already exists.`,\n\t\t\t\t\t\tduplicateValue: draft.email,\n\t\t\t\t\t\tfield: \"email\",\n\t\t\t\t\t} as DuplicateFieldError,\n\t\t\t\t],\n\t\t\t});\n\t\t}\n\n\t\tconst addresses: Address[] =\n\t\t\tdraft.addresses?.map((address) => ({\n\t\t\t\t...address,\n\t\t\t\tid: generateRandomString(5),\n\t\t\t})) ?? [];\n\n\t\tconst lookupAdressId = (\n\t\t\taddresses: Address[],\n\t\t\taddressId: number,\n\t\t): string => {\n\t\t\tif (addressId < addresses.length) {\n\t\t\t\tconst id = addresses[addressId].id;\n\t\t\t\tif (!id) {\n\t\t\t\t\tthrow new Error(\"Address ID is missing\");\n\t\t\t\t}\n\t\t\t\treturn id;\n\t\t\t}\n\t\t\tthrow new CommercetoolsError<InvalidInputError>({\n\t\t\t\tcode: \"InvalidInput\",\n\t\t\t\tmessage: `Address with ID '${addressId}' not found.`,\n\t\t\t\terrors: [\n\t\t\t\t\t{\n\t\t\t\t\t\tcode: \"InvalidInput\",\n\t\t\t\t\t\tmessage: `Address with ID '${addressId}' not found.`,\n\t\t\t\t\t\tfield: \"addressId\",\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t});\n\t\t};\n\n\t\tconst defaultBillingAddressId =\n\t\t\tdraft.defaultBillingAddress !== undefined\n\t\t\t\t? lookupAdressId(addresses, draft.defaultBillingAddress)\n\t\t\t\t: undefined;\n\t\tconst defaultShippingAddressId =\n\t\t\tdraft.defaultShippingAddress !== undefined\n\t\t\t\t? lookupAdressId(addresses, draft.defaultShippingAddress)\n\t\t\t\t: undefined;\n\t\tconst shippingAddressIds =\n\t\t\tdraft.shippingAddresses?.map((addressId) =>\n\t\t\t\tlookupAdressId(addresses, addressId),\n\t\t\t) ?? [];\n\t\tconst billingAddressIds =\n\t\t\tdraft.billingAddresses?.map((addressId) =>\n\t\t\t\tlookupAdressId(addresses, addressId),\n\t\t\t) ?? [];\n\n\t\tlet storesForCustomer: StoreKeyReference[] = [];\n\n\t\tif (draft.stores && draft.stores.length > 0) {\n\t\t\tstoresForCustomer = this.storeReferenceToStoreKeyReference(\n\t\t\t\tdraft.stores,\n\t\t\t\tcontext.projectKey,\n\t\t\t);\n\t\t}\n\n\t\tconst resource: Customer = {\n\t\t\t...getBaseResourceProperties(),\n\t\t\tkey: draft.key,\n\t\t\tauthenticationMode: draft.authenticationMode || \"Password\",\n\t\t\tfirstName: draft.firstName,\n\t\t\tlastName: draft.lastName,\n\t\t\tmiddleName: draft.middleName,\n\t\t\ttitle: draft.title,\n\t\t\tdateOfBirth: draft.dateOfBirth,\n\t\t\tcompanyName: draft.companyName,\n\t\t\temail: draft.email.toLowerCase(),\n\t\t\tlowercaseEmail: draft.email.toLowerCase(),\n\t\t\tpassword: draft.password ? hashPassword(draft.password) : undefined,\n\t\t\tisEmailVerified: draft.isEmailVerified || false,\n\t\t\taddresses: addresses,\n\t\t\tcustomerNumber: draft.customerNumber,\n\t\t\texternalId: draft.externalId,\n\t\t\tdefaultBillingAddressId: defaultBillingAddressId,\n\t\t\tdefaultShippingAddressId: defaultShippingAddressId,\n\t\t\tshippingAddressIds: shippingAddressIds,\n\t\t\tbillingAddressIds: billingAddressIds,\n\t\t\tcustom: createCustomFields(\n\t\t\t\tdraft.custom,\n\t\t\t\tcontext.projectKey,\n\t\t\t\tthis._storage,\n\t\t\t),\n\t\t\tstores: storesForCustomer,\n\t\t} satisfies unknown as Customer;\n\n\t\treturn this.saveNew(context, resource);\n\t}\n\n\tsaveUpdate(\n\t\tcontext: RepositoryContext,\n\t\tversion: number,\n\t\tresource: ShallowWritable<ResourceMap[\"customer\"]>,\n\t): ShallowWritable<ResourceMap[\"customer\"]> {\n\t\t// Also update lowercaseEmail attribute\n\t\tconst updatedResource: Customer = {\n\t\t\t...resource,\n\t\t\tlowercaseEmail: resource.email.toLowerCase(),\n\t\t} satisfies unknown as Customer;\n\n\t\treturn super.saveUpdate(context, version, updatedResource);\n\t}\n\n\tpasswordResetToken(\n\t\tcontext: RepositoryContext,\n\t\trequest: CustomerCreatePasswordResetToken,\n\t): CustomerToken {\n\t\tconst results = this._storage.query(context.projectKey, this.getTypeId(), {\n\t\t\twhere: [`email=\"${request.email.toLocaleLowerCase()}\"`],\n\t\t});\n\t\tif (results.count === 0) {\n\t\t\tthrow new CommercetoolsError<ResourceNotFoundError>({\n\t\t\t\tcode: \"ResourceNotFound\",\n\t\t\t\tmessage: `The Customer with ID '${request.email}' was not found.`,\n\t\t\t});\n\t\t}\n\n\t\tconst ttlMinutes = request.ttlMinutes ?? 34560; // 34560 is CT default\n\n\t\tconst expiresAt = new Date(Date.now() + ttlMinutes * 60 * 1000);\n\t\tconst customer = results.results[0] as Customer;\n\t\tconst rest = getBaseResourceProperties();\n\n\t\tconst token = createPasswordResetToken(customer, expiresAt);\n\n\t\treturn {\n\t\t\tid: rest.id,\n\t\t\tcreatedAt: rest.createdAt,\n\t\t\tlastModifiedAt: rest.lastModifiedAt,\n\t\t\tcustomerId: customer.id,\n\t\t\texpiresAt: expiresAt.toISOString(),\n\t\t\tvalue: token,\n\t\t\tinvalidateOlderTokens: request.invalidateOlderTokens || false,\n\t\t};\n\t}\n\n\tpasswordReset(\n\t\tcontext: RepositoryContext,\n\t\tresetPassword: CustomerResetPassword | MyCustomerResetPassword,\n\t) {\n\t\tconst { newPassword, tokenValue } = resetPassword;\n\n\t\tconst customerId = validatePasswordResetToken(tokenValue);\n\t\tif (!customerId) {\n\t\t\tthrow new CommercetoolsError<ResourceNotFoundError>({\n\t\t\t\tcode: \"ResourceNotFound\",\n\t\t\t\tmessage: `The Customer with ID 'Token(${tokenValue})' was not found.`,\n\t\t\t});\n\t\t}\n\n\t\tconst customer = this._storage.get(\n\t\t\tcontext.projectKey,\n\t\t\t\"customer\",\n\t\t\tcustomerId,\n\t\t) as Writable<Customer> | undefined;\n\n\t\tif (!customer) {\n\t\t\tthrow new CommercetoolsError<ResourceNotFoundError>({\n\t\t\t\tcode: \"ResourceNotFound\",\n\t\t\t\tmessage: `The Customer with ID 'Token(${tokenValue})' was not found.`,\n\t\t\t});\n\t\t}\n\n\t\tcustomer.password = hashPassword(newPassword);\n\t\tcustomer.version += 1;\n\n\t\t// Update storage\n\t\tthis._storage.add(context.projectKey, \"customer\", customer);\n\t\treturn customer;\n\t}\n\n\tverifyEmailToken(context: RepositoryContext, id: string): CustomerToken {\n\t\tconst results = this._storage.query(context.projectKey, this.getTypeId(), {\n\t\t\twhere: [`id=\"${id.toLocaleLowerCase()}\"`],\n\t\t});\n\t\tif (results.count === 0) {\n\t\t\tthrow new CommercetoolsError<ResourceNotFoundError>({\n\t\t\t\tcode: \"ResourceNotFound\",\n\t\t\t\tmessage: `The Customer with ID '${id}' was not found.`,\n\t\t\t});\n\t\t}\n\t\tconst expiresAt = new Date(Date.now() + 30 * 60);\n\t\tconst customer = results.results[0] as Customer;\n\t\tconst rest = getBaseResourceProperties();\n\n\t\tconst token = createEmailVerifyToken(customer);\n\t\treturn {\n\t\t\tid: rest.id,\n\t\t\tcreatedAt: rest.createdAt,\n\t\t\tlastModifiedAt: rest.lastModifiedAt,\n\t\t\tcustomerId: customer.id,\n\t\t\texpiresAt: expiresAt.toISOString(),\n\t\t\tvalue: token,\n\t\t\tinvalidateOlderTokens: false,\n\t\t};\n\t}\n\n\tprivate storeReferenceToStoreKeyReference(\n\t\tdraftStores: StoreResourceIdentifier[],\n\t\tprojectKey: string,\n\t): StoreKeyReference[] {\n\t\tconst storeIds = draftStores\n\t\t\t.map((storeReference) => storeReference.id)\n\t\t\t.filter(Boolean);\n\n\t\tlet stores: Store[] = [];\n\n\t\tif (storeIds.length > 0) {\n\t\t\tstores = this._storage.query(projectKey, \"store\", {\n\t\t\t\twhere: storeIds.map((id) => `id=\"${id}\"`),\n\t\t\t}).results;\n\n\t\t\tif (storeIds.length !== stores.length) {\n\t\t\t\tthrow new CommercetoolsError<ResourceNotFoundError>({\n\t\t\t\t\tcode: \"ResourceNotFound\",\n\t\t\t\t\tmessage: `Store with ID '${storeIds.find((id) => !stores.some((store) => store.id === id))}' was not found.`,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\treturn draftStores.map((storeReference) => ({\n\t\t\ttypeId: \"store\",\n\t\t\tkey:\n\t\t\t\tstoreReference.key ??\n\t\t\t\t(stores.find((store) => store.id === storeReference.id)?.key as string),\n\t\t}));\n\t}\n}\n","import type {\n\tCustomerGroup,\n\tCustomerGroupChangeNameAction,\n\tCustomerGroupDraft,\n\tCustomerGroupSetCustomFieldAction,\n\tCustomerGroupSetCustomTypeAction,\n\tCustomerGroupSetKeyAction,\n\tCustomerGroupUpdateAction,\n} from \"@commercetools/platform-sdk\";\nimport type { Config } from \"#src/config.ts\";\nimport { getBaseResourceProperties } from \"../helpers.ts\";\nimport type { Writable } from \"../types.ts\";\nimport type { UpdateHandlerInterface } from \"./abstract.ts\";\nimport {\n\tAbstractResourceRepository,\n\tAbstractUpdateHandler,\n\ttype RepositoryContext,\n} from \"./abstract.ts\";\nimport { createCustomFields } from \"./helpers.ts\";\n\nexport class CustomerGroupRepository extends AbstractResourceRepository<\"customer-group\"> {\n\tconstructor(config: Config) {\n\t\tsuper(\"customer-group\", config);\n\t\tthis.actions = new CustomerGroupUpdateHandler(config.storage);\n\t}\n\n\tcreate(context: RepositoryContext, draft: CustomerGroupDraft): CustomerGroup {\n\t\tconst resource: CustomerGroup = {\n\t\t\t...getBaseResourceProperties(),\n\t\t\tkey: draft.key,\n\t\t\tname: draft.groupName,\n\t\t\tcustom: createCustomFields(\n\t\t\t\tdraft.custom,\n\t\t\t\tcontext.projectKey,\n\t\t\t\tthis._storage,\n\t\t\t),\n\t\t};\n\t\treturn this.saveNew(context, resource);\n\t}\n}\n\nclass CustomerGroupUpdateHandler\n\textends AbstractUpdateHandler\n\timplements UpdateHandlerInterface<CustomerGroup, CustomerGroupUpdateAction>\n{\n\tchangeName(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<CustomerGroup>,\n\t\t{ name }: CustomerGroupChangeNameAction,\n\t) {\n\t\tresource.name = name;\n\t}\n\n\tsetCustomField(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<CustomerGroup>,\n\t\t{ name, value }: CustomerGroupSetCustomFieldAction,\n\t) {\n\t\tif (!resource.custom) {\n\t\t\treturn;\n\t\t}\n\t\tif (value === null) {\n\t\t\tdelete resource.custom.fields[name];\n\t\t} else {\n\t\t\tresource.custom.fields[name] = value;\n\t\t}\n\t}\n\n\tsetCustomType(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<CustomerGroup>,\n\t\t{ type, fields }: CustomerGroupSetCustomTypeAction,\n\t) {\n\t\tif (type) {\n\t\t\tresource.custom = createCustomFields(\n\t\t\t\t{ type, fields },\n\t\t\t\tcontext.projectKey,\n\t\t\t\tthis._storage,\n\t\t\t);\n\t\t} else {\n\t\t\tresource.custom = undefined;\n\t\t}\n\t}\n\n\tsetKey(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<CustomerGroup>,\n\t\t{ key }: CustomerGroupSetKeyAction,\n\t) {\n\t\tresource.key = key;\n\t}\n}\n","import type {\n\tCartDiscountReference,\n\tDiscountCode,\n\tDiscountCodeChangeCartDiscountsAction,\n\tDiscountCodeChangeIsActiveAction,\n\tDiscountCodeSetCartPredicateAction,\n\tDiscountCodeSetCustomFieldAction,\n\tDiscountCodeSetCustomTypeAction,\n\tDiscountCodeSetDescriptionAction,\n\tDiscountCodeSetMaxApplicationsAction,\n\tDiscountCodeSetMaxApplicationsPerCustomerAction,\n\tDiscountCodeSetNameAction,\n\tDiscountCodeSetValidFromAction,\n\tDiscountCodeSetValidFromAndUntilAction,\n\tDiscountCodeSetValidUntilAction,\n\tDiscountCodeUpdateAction,\n} from \"@commercetools/platform-sdk\";\nimport type { Writable } from \"#src/types.ts\";\nimport type { UpdateHandlerInterface } from \"../abstract.ts\";\nimport { AbstractUpdateHandler, type RepositoryContext } from \"../abstract.ts\";\nimport { createCustomFields } from \"../helpers.ts\";\n\nexport class DiscountCodeUpdateHandler\n\textends AbstractUpdateHandler\n\timplements\n\t\tPartial<UpdateHandlerInterface<DiscountCode, DiscountCodeUpdateAction>>\n{\n\tchangeCartDiscounts(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<DiscountCode>,\n\t\t{ cartDiscounts }: DiscountCodeChangeCartDiscountsAction,\n\t) {\n\t\tresource.cartDiscounts = cartDiscounts.map(\n\t\t\t(obj): CartDiscountReference => ({\n\t\t\t\ttypeId: \"cart-discount\",\n\t\t\t\tid: obj.id!,\n\t\t\t}),\n\t\t);\n\t}\n\n\tchangeIsActive(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<DiscountCode>,\n\t\t{ isActive }: DiscountCodeChangeIsActiveAction,\n\t) {\n\t\tresource.isActive = isActive;\n\t}\n\n\tsetCartPredicate(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<DiscountCode>,\n\t\t{ cartPredicate }: DiscountCodeSetCartPredicateAction,\n\t) {\n\t\tresource.cartPredicate = cartPredicate;\n\t}\n\n\tsetCustomField(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<DiscountCode>,\n\t\t{ name, value }: DiscountCodeSetCustomFieldAction,\n\t) {\n\t\tif (!resource.custom) {\n\t\t\treturn;\n\t\t}\n\t\tif (value === null) {\n\t\t\tdelete resource.custom.fields[name];\n\t\t} else {\n\t\t\tresource.custom.fields[name] = value;\n\t\t}\n\t}\n\n\tsetCustomType(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<DiscountCode>,\n\t\t{ type, fields }: DiscountCodeSetCustomTypeAction,\n\t) {\n\t\tif (type) {\n\t\t\tresource.custom = createCustomFields(\n\t\t\t\t{ type, fields },\n\t\t\t\tcontext.projectKey,\n\t\t\t\tthis._storage,\n\t\t\t);\n\t\t} else {\n\t\t\tresource.custom = undefined;\n\t\t}\n\t}\n\n\tsetDescription(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<DiscountCode>,\n\t\t{ description }: DiscountCodeSetDescriptionAction,\n\t) {\n\t\tresource.description = description;\n\t}\n\n\tsetMaxApplications(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<DiscountCode>,\n\t\t{ maxApplications }: DiscountCodeSetMaxApplicationsAction,\n\t) {\n\t\tresource.maxApplications = maxApplications;\n\t}\n\n\tsetMaxApplicationsPerCustomer(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<DiscountCode>,\n\t\t{\n\t\t\tmaxApplicationsPerCustomer,\n\t\t}: DiscountCodeSetMaxApplicationsPerCustomerAction,\n\t) {\n\t\tresource.maxApplicationsPerCustomer = maxApplicationsPerCustomer;\n\t}\n\n\tsetName(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<DiscountCode>,\n\t\t{ name }: DiscountCodeSetNameAction,\n\t) {\n\t\tresource.name = name;\n\t}\n\n\tsetValidFrom(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<DiscountCode>,\n\t\t{ validFrom }: DiscountCodeSetValidFromAction,\n\t) {\n\t\tresource.validFrom = validFrom;\n\t}\n\n\tsetValidFromAndUntil(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<DiscountCode>,\n\t\t{ validFrom, validUntil }: DiscountCodeSetValidFromAndUntilAction,\n\t) {\n\t\tresource.validFrom = validFrom;\n\t\tresource.validUntil = validUntil;\n\t}\n\n\tsetValidUntil(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<DiscountCode>,\n\t\t{ validUntil }: DiscountCodeSetValidUntilAction,\n\t) {\n\t\tresource.validUntil = validUntil;\n\t}\n}\n","import type {\n\tCartDiscountReference,\n\tDiscountCode,\n\tDiscountCodeDraft,\n} from \"@commercetools/platform-sdk\";\nimport type { Config } from \"#src/config.ts\";\nimport { getBaseResourceProperties } from \"#src/helpers.ts\";\nimport {\n\tAbstractResourceRepository,\n\ttype RepositoryContext,\n} from \"../abstract.ts\";\nimport { createCustomFields } from \"../helpers.ts\";\nimport { DiscountCodeUpdateHandler } from \"./actions.ts\";\n\nexport class DiscountCodeRepository extends AbstractResourceRepository<\"discount-code\"> {\n\tconstructor(config: Config) {\n\t\tsuper(\"discount-code\", config);\n\t\tthis.actions = new DiscountCodeUpdateHandler(config.storage);\n\t}\n\n\tcreate(context: RepositoryContext, draft: DiscountCodeDraft): DiscountCode {\n\t\tconst resource: DiscountCode = {\n\t\t\t...getBaseResourceProperties(),\n\t\t\tapplicationVersion: 1,\n\t\t\tcartDiscounts: draft.cartDiscounts.map(\n\t\t\t\t(obj): CartDiscountReference => ({\n\t\t\t\t\ttypeId: \"cart-discount\",\n\t\t\t\t\tid: obj.id!,\n\t\t\t\t}),\n\t\t\t),\n\t\t\tcartPredicate: draft.cartPredicate,\n\t\t\tcode: draft.code,\n\t\t\tdescription: draft.description,\n\t\t\tgroups: draft.groups || [],\n\t\t\tisActive: draft.isActive || true,\n\t\t\tname: draft.name,\n\t\t\treferences: [],\n\t\t\tvalidFrom: draft.validFrom,\n\t\t\tvalidUntil: draft.validUntil,\n\t\t\tmaxApplications: draft.maxApplications,\n\t\t\tmaxApplicationsPerCustomer: draft.maxApplicationsPerCustomer,\n\t\t\tcustom: createCustomFields(\n\t\t\t\tdraft.custom,\n\t\t\t\tcontext.projectKey,\n\t\t\t\tthis._storage,\n\t\t\t),\n\t\t};\n\t\treturn this.saveNew(context, resource);\n\t}\n}\n","import type {\n\tDiscountGroup,\n\tDiscountGroupSetDescriptionAction,\n\tDiscountGroupSetKeyAction,\n\tDiscountGroupSetNameAction,\n\tDiscountGroupSetSortOrderAction,\n\tDiscountGroupUpdateAction,\n} from \"@commercetools/platform-sdk\";\nimport type { Writable } from \"#src/types.ts\";\nimport type { UpdateHandlerInterface } from \"../abstract.ts\";\nimport { AbstractUpdateHandler, type RepositoryContext } from \"../abstract.ts\";\n\nexport class DiscountGroupUpdateHandler\n\textends AbstractUpdateHandler\n\timplements\n\t\tPartial<UpdateHandlerInterface<DiscountGroup, DiscountGroupUpdateAction>>\n{\n\tsetDescription(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<DiscountGroup>,\n\t\t{ description }: DiscountGroupSetDescriptionAction,\n\t) {\n\t\tresource.description = description;\n\t}\n\n\tsetKey(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<DiscountGroup>,\n\t\t{ key }: DiscountGroupSetKeyAction,\n\t) {\n\t\tresource.key = key;\n\t}\n\n\tsetName(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<DiscountGroup>,\n\t\t{ name }: DiscountGroupSetNameAction,\n\t) {\n\t\tresource.name = name;\n\t}\n\n\tsetSortOrder(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<DiscountGroup>,\n\t\t{ sortOrder }: DiscountGroupSetSortOrderAction,\n\t) {\n\t\tresource.sortOrder = sortOrder;\n\t}\n}\n","import type {\n\tDiscountGroup,\n\tDiscountGroupDraft,\n} from \"@commercetools/platform-sdk\";\nimport type { Config } from \"#src/config.ts\";\nimport { getBaseResourceProperties } from \"#src/helpers.ts\";\nimport {\n\tAbstractResourceRepository,\n\ttype RepositoryContext,\n} from \"../abstract.ts\";\nimport { DiscountGroupUpdateHandler } from \"./actions.ts\";\n\nexport class DiscountGroupRepository extends AbstractResourceRepository<\"discount-group\"> {\n\tconstructor(config: Config) {\n\t\tsuper(\"discount-group\", config);\n\t\tthis.actions = new DiscountGroupUpdateHandler(config.storage);\n\t}\n\n\tcreate(context: RepositoryContext, draft: DiscountGroupDraft): DiscountGroup {\n\t\tconst resource: DiscountGroup = {\n\t\t\t...getBaseResourceProperties(),\n\t\t\tdescription: draft.description,\n\t\t\tname: draft.name,\n\t\t\tkey: draft.key,\n\t\t\tsortOrder: draft.sortOrder,\n\t\t\tisActive: true,\n\t\t};\n\t\treturn this.saveNew(context, resource);\n\t}\n}\n","import { cloneObject } from \"../helpers.ts\";\n\nexport const maskSecretValue = <T>(resource: T, path: string): T => {\n\tconst parts = path.split(\".\");\n\tconst clone = cloneObject(resource) as any;\n\tlet val = clone;\n\n\tconst target = parts.pop();\n\tfor (let i = 0; i < parts.length; i++) {\n\t\tconst part = parts[i];\n\t\tval = val[part];\n\n\t\tif (val === undefined) {\n\t\t\treturn resource;\n\t\t}\n\t}\n\n\tif (val && target && val[target]) {\n\t\tval[target] = \"****\";\n\t}\n\treturn clone;\n};\n","import type {\n\tExtension,\n\tExtensionChangeDestinationAction,\n\tExtensionChangeTriggersAction,\n\tExtensionDraft,\n\tExtensionSetKeyAction,\n\tExtensionSetTimeoutInMsAction,\n\tExtensionUpdateAction,\n} from \"@commercetools/platform-sdk\";\nimport type { Config } from \"#src/config.ts\";\nimport { getBaseResourceProperties } from \"../helpers.ts\";\nimport { maskSecretValue } from \"../lib/masking.ts\";\nimport type { Writable } from \"../types.ts\";\nimport type { UpdateHandlerInterface } from \"./abstract.ts\";\nimport {\n\tAbstractResourceRepository,\n\tAbstractUpdateHandler,\n\ttype RepositoryContext,\n} from \"./abstract.ts\";\n\nexport class ExtensionRepository extends AbstractResourceRepository<\"extension\"> {\n\tconstructor(config: Config) {\n\t\tsuper(\"extension\", config);\n\t\tthis.actions = new ExtensionUpdateHandler(config.storage);\n\t}\n\n\tcreate(context: RepositoryContext, draft: ExtensionDraft): Extension {\n\t\tconst resource: Extension = {\n\t\t\t...getBaseResourceProperties(),\n\t\t\tkey: draft.key,\n\t\t\ttimeoutInMs: draft.timeoutInMs,\n\t\t\tdestination: draft.destination,\n\t\t\ttriggers: draft.triggers,\n\t\t};\n\t\treturn this.saveNew(context, resource);\n\t}\n\n\tpostProcessResource(\n\t\tcontext: RepositoryContext,\n\t\tresource: Extension,\n\t): Extension {\n\t\tif (resource) {\n\t\t\tconst extension = resource as Extension;\n\t\t\tif (\n\t\t\t\textension.destination.type === \"HTTP\" &&\n\t\t\t\textension.destination.authentication?.type === \"AuthorizationHeader\"\n\t\t\t) {\n\t\t\t\treturn maskSecretValue(\n\t\t\t\t\textension,\n\t\t\t\t\t\"destination.authentication.headerValue\",\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (extension.destination.type === \"AWSLambda\") {\n\t\t\t\treturn maskSecretValue(resource, \"destination.accessSecret\");\n\t\t\t}\n\t\t}\n\t\treturn resource;\n\t}\n}\n\nclass ExtensionUpdateHandler\n\textends AbstractUpdateHandler\n\timplements UpdateHandlerInterface<Extension, ExtensionUpdateAction>\n{\n\tchangeDestination(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Extension>,\n\t\taction: ExtensionChangeDestinationAction,\n\t): void {\n\t\tresource.destination = action.destination;\n\t}\n\n\tchangeTriggers(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Extension>,\n\t\taction: ExtensionChangeTriggersAction,\n\t): void {\n\t\tresource.triggers = action.triggers;\n\t}\n\n\tsetKey(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Extension>,\n\t\taction: ExtensionSetKeyAction,\n\t): void {\n\t\tresource.key = action.key;\n\t}\n\n\tsetTimeoutInMs(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Extension>,\n\t\taction: ExtensionSetTimeoutInMsAction,\n\t): void {\n\t\tresource.timeoutInMs = action.timeoutInMs;\n\t}\n}\n","import type {\n\tInventoryEntry,\n\tInventoryEntryChangeQuantityAction,\n\tInventoryEntryRemoveQuantityAction,\n\tInventoryEntrySetCustomFieldAction,\n\tInventoryEntrySetCustomTypeAction,\n\tInventoryEntrySetExpectedDeliveryAction,\n\tInventoryEntrySetRestockableInDaysAction,\n\tInventoryEntryUpdateAction,\n} from \"@commercetools/platform-sdk\";\nimport type { Writable } from \"#src/types.ts\";\nimport type { UpdateHandlerInterface } from \"../abstract.ts\";\nimport { AbstractUpdateHandler, type RepositoryContext } from \"../abstract.ts\";\n\nexport class InventoryEntryUpdateHandler\n\textends AbstractUpdateHandler\n\timplements\n\t\tPartial<UpdateHandlerInterface<InventoryEntry, InventoryEntryUpdateAction>>\n{\n\tchangeQuantity(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<InventoryEntry>,\n\t\t{ quantity }: InventoryEntryChangeQuantityAction,\n\t) {\n\t\tresource.quantityOnStock = quantity;\n\t\t// don't know active reservations so just set to same value\n\t\tresource.availableQuantity = quantity;\n\t}\n\n\tremoveQuantity(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<InventoryEntry>,\n\t\t{ quantity }: InventoryEntryRemoveQuantityAction,\n\t) {\n\t\tconst newQuantity = Math.max(0, resource.quantityOnStock - quantity);\n\t\tresource.quantityOnStock = newQuantity;\n\t\t// don't know active reservations so just set to same value\n\t\tresource.availableQuantity = newQuantity;\n\t}\n\n\tsetCustomField(\n\t\tcontext: RepositoryContext,\n\t\tresource: InventoryEntry,\n\t\t{ name, value }: InventoryEntrySetCustomFieldAction,\n\t) {\n\t\tif (!resource.custom) {\n\t\t\tthrow new Error(\"Resource has no custom field\");\n\t\t}\n\t\tresource.custom.fields[name] = value;\n\t}\n\n\tsetCustomType(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<InventoryEntry>,\n\t\t{ type, fields }: InventoryEntrySetCustomTypeAction,\n\t) {\n\t\tif (!type) {\n\t\t\tresource.custom = undefined;\n\t\t} else {\n\t\t\tconst resolvedType = this._storage.getByResourceIdentifier(\n\t\t\t\tcontext.projectKey,\n\t\t\t\ttype,\n\t\t\t);\n\t\t\tif (!resolvedType) {\n\t\t\t\tthrow new Error(`Type ${type} not found`);\n\t\t\t}\n\n\t\t\tresource.custom = {\n\t\t\t\ttype: {\n\t\t\t\t\ttypeId: \"type\",\n\t\t\t\t\tid: resolvedType.id,\n\t\t\t\t},\n\t\t\t\tfields: fields || {},\n\t\t\t};\n\t\t}\n\t}\n\n\tsetExpectedDelivery(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<InventoryEntry>,\n\t\t{ expectedDelivery }: InventoryEntrySetExpectedDeliveryAction,\n\t) {\n\t\tresource.expectedDelivery = new Date(expectedDelivery!).toISOString();\n\t}\n\n\tsetRestockableInDays(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<InventoryEntry>,\n\t\t{ restockableInDays }: InventoryEntrySetRestockableInDaysAction,\n\t) {\n\t\tresource.restockableInDays = restockableInDays;\n\t}\n}\n","import type {\n\tInventoryEntry,\n\tInventoryEntryDraft,\n} from \"@commercetools/platform-sdk\";\nimport type { Config } from \"#src/config.ts\";\nimport { getBaseResourceProperties } from \"#src/helpers.ts\";\nimport {\n\tAbstractResourceRepository,\n\ttype RepositoryContext,\n} from \"../abstract.ts\";\nimport { createCustomFields } from \"../helpers.ts\";\nimport { InventoryEntryUpdateHandler } from \"./actions.ts\";\n\nexport class InventoryEntryRepository extends AbstractResourceRepository<\"inventory-entry\"> {\n\tconstructor(config: Config) {\n\t\tsuper(\"inventory-entry\", config);\n\t\tthis.actions = new InventoryEntryUpdateHandler(config.storage);\n\t}\n\n\tcreate(\n\t\tcontext: RepositoryContext,\n\t\tdraft: InventoryEntryDraft,\n\t): InventoryEntry {\n\t\tconst resource: InventoryEntry = {\n\t\t\t...getBaseResourceProperties(),\n\t\t\tsku: draft.sku,\n\t\t\tquantityOnStock: draft.quantityOnStock,\n\t\t\tavailableQuantity: draft.quantityOnStock,\n\t\t\texpectedDelivery: draft.expectedDelivery,\n\t\t\trestockableInDays: draft.restockableInDays,\n\t\t\tsupplyChannel: {\n\t\t\t\t...draft.supplyChannel,\n\t\t\t\ttypeId: \"channel\",\n\t\t\t\tid: draft.supplyChannel?.id ?? \"\",\n\t\t\t},\n\t\t\tcustom: createCustomFields(\n\t\t\t\tdraft.custom,\n\t\t\t\tcontext.projectKey,\n\t\t\t\tthis._storage,\n\t\t\t),\n\t\t};\n\t\treturn this.saveNew(context, resource);\n\t}\n}\n","import type {\n\tCustomer,\n\tInvalidCurrentPasswordError,\n\tMyCustomerChangePassword,\n\tMyCustomerEmailVerify,\n\tResourceNotFoundError,\n} from \"@commercetools/platform-sdk\";\nimport { CommercetoolsError } from \"#src/exceptions.ts\";\nimport { hashPassword, validateEmailVerifyToken } from \"../lib/password.ts\";\nimport type { Writable } from \"../types.ts\";\nimport type { RepositoryContext } from \"./abstract.ts\";\nimport { CustomerRepository } from \"./customer/index.ts\";\n\nexport class MyCustomerRepository extends CustomerRepository {\n\tchangePassword(\n\t\tcontext: RepositoryContext,\n\t\tchangePassword: MyCustomerChangePassword,\n\t) {\n\t\tconst { currentPassword, newPassword } = changePassword;\n\t\tconst encodedPassword = hashPassword(currentPassword);\n\n\t\tconst result = this._storage.query(context.projectKey, \"customer\", {\n\t\t\twhere: [`password = \"${encodedPassword}\"`],\n\t\t});\n\t\tif (result.count === 0) {\n\t\t\tthrow new CommercetoolsError<InvalidCurrentPasswordError>({\n\t\t\t\tcode: \"InvalidCurrentPassword\",\n\t\t\t\tmessage: \"Account with the given credentials not found.\",\n\t\t\t});\n\t\t}\n\n\t\tconst customer = result.results[0] as Writable<Customer>;\n\t\tif (customer.password !== hashPassword(currentPassword)) {\n\t\t\tthrow new CommercetoolsError<InvalidCurrentPasswordError>({\n\t\t\t\tcode: \"InvalidCurrentPassword\",\n\t\t\t\tmessage: \"The current password is invalid.\",\n\t\t\t});\n\t\t}\n\n\t\tcustomer.password = hashPassword(newPassword);\n\t\tcustomer.version += 1;\n\n\t\t// Update storage\n\t\tthis._storage.add(context.projectKey, \"customer\", customer);\n\t\treturn customer;\n\t}\n\n\tconfirmEmail(\n\t\tcontext: RepositoryContext,\n\t\tresetPassword: MyCustomerEmailVerify,\n\t) {\n\t\tconst { tokenValue } = resetPassword;\n\n\t\tconst customerId = validateEmailVerifyToken(tokenValue);\n\t\tif (!customerId) {\n\t\t\tthrow new CommercetoolsError<ResourceNotFoundError>({\n\t\t\t\tcode: \"ResourceNotFound\",\n\t\t\t\tmessage: `The Customer with ID 'Token(${tokenValue})' was not found.`,\n\t\t\t});\n\t\t}\n\n\t\tconst customer = this._storage.get(\n\t\t\tcontext.projectKey,\n\t\t\t\"customer\",\n\t\t\tcustomerId,\n\t\t) as Writable<Customer> | undefined;\n\n\t\tif (!customer) {\n\t\t\tthrow new CommercetoolsError<ResourceNotFoundError>({\n\t\t\t\tcode: \"ResourceNotFound\",\n\t\t\t\tmessage: `The Customer with ID 'Token(${tokenValue})' was not found.`,\n\t\t\t});\n\t\t}\n\n\t\tcustomer.isEmailVerified = true;\n\t\tcustomer.version += 1;\n\n\t\t// Update storage\n\t\tthis._storage.add(context.projectKey, \"customer\", customer);\n\t\treturn customer;\n\t}\n\n\tdeleteMe(context: RepositoryContext): Customer | undefined {\n\t\t// grab the first customer you can find for now. In the future we should\n\t\t// use the customer id from the scope of the token\n\t\tconst results = this._storage.query(\n\t\t\tcontext.projectKey,\n\t\t\tthis.getTypeId(),\n\t\t\t{},\n\t\t);\n\n\t\tif (results.count > 0) {\n\t\t\treturn this.delete(context, results.results[0].id) as Customer;\n\t\t}\n\n\t\treturn;\n\t}\n\n\tgetMe(context: RepositoryContext): Customer | undefined {\n\t\t// grab the first customer you can find for now. In the future we should\n\t\t// use the customer id from the scope of the token\n\t\tconst results = this._storage.query(\n\t\t\tcontext.projectKey,\n\t\t\tthis.getTypeId(),\n\t\t\t{},\n\t\t);\n\n\t\tif (results.count > 0) {\n\t\t\treturn results.results[0] as Customer;\n\t\t}\n\n\t\treturn;\n\t}\n}\n","import assert from \"node:assert\";\nimport type {\n\tCartReference,\n\tMyOrderFromCartDraft,\n\tOrder,\n} from \"@commercetools/platform-sdk\";\nimport type { RepositoryContext } from \"./abstract.ts\";\nimport { OrderRepository } from \"./order/index.ts\";\n\nexport class MyOrderRepository extends OrderRepository {\n\tcreate(context: RepositoryContext, draft: MyOrderFromCartDraft): Order {\n\t\tassert(draft.id, \"draft.id is missing\");\n\t\tconst cartIdentifier = {\n\t\t\tid: draft.id,\n\t\t\ttypeId: \"cart\",\n\t\t} as CartReference;\n\t\treturn this.createFromCart(context, cartIdentifier);\n\t}\n}\n","import type {\n\tOrderEdit,\n\tOrderEditDraft,\n\tOrderEditResult,\n} from \"@commercetools/platform-sdk\";\nimport type { Config } from \"#src/config.ts\";\nimport { getBaseResourceProperties } from \"../helpers.ts\";\nimport type { RepositoryContext } from \"./abstract.ts\";\nimport { AbstractResourceRepository } from \"./abstract.ts\";\n\nexport class OrderEditRepository extends AbstractResourceRepository<\"order-edit\"> {\n\tconstructor(config: Config) {\n\t\tsuper(\"order-edit\", config);\n\t}\n\n\tcreate(context: RepositoryContext, draft: OrderEditDraft): OrderEdit {\n\t\tconst resource: OrderEdit = {\n\t\t\t...getBaseResourceProperties(),\n\t\t\tstagedActions: draft.stagedActions ?? [],\n\t\t\tresource: draft.resource,\n\t\t\tresult: {\n\t\t\t\ttype: \"NotProcessed\",\n\t\t\t} as OrderEditResult,\n\t\t};\n\t\treturn this.saveNew(context, resource);\n\t}\n}\n","import type {\n\tTransaction,\n\tTransactionDraft,\n} from \"@commercetools/platform-sdk\";\nimport { v4 as uuidv4 } from \"uuid\";\nimport type { AbstractStorage } from \"#src/storage/index.ts\";\nimport type { RepositoryContext } from \"../abstract.ts\";\nimport { createCentPrecisionMoney, createCustomFields } from \"../helpers.ts\";\n\nexport const transactionFromTransactionDraft = (\n\tcontext: RepositoryContext,\n\tstorage: AbstractStorage,\n\tdraft: TransactionDraft,\n): Transaction => ({\n\t...draft,\n\tid: uuidv4(),\n\tamount: createCentPrecisionMoney(draft.amount),\n\tcustom: createCustomFields(draft.custom, context.projectKey, storage),\n\tstate: draft.state ?? \"Initial\", // Documented as default\n});\n","import type {\n\tCustomerReference,\n\tPayment,\n\tPaymentAddInterfaceInteractionAction,\n\tPaymentAddTransactionAction,\n\tPaymentChangeAmountPlannedAction,\n\tPaymentChangeTransactionInteractionIdAction,\n\tPaymentChangeTransactionStateAction,\n\tPaymentChangeTransactionTimestampAction,\n\tPaymentSetAnonymousIdAction,\n\tPaymentSetCustomerAction,\n\tPaymentSetCustomFieldAction,\n\tPaymentSetCustomTypeAction,\n\tPaymentSetInterfaceIdAction,\n\tPaymentSetKeyAction,\n\tPaymentSetMethodInfoAction,\n\tPaymentSetMethodInfoCustomFieldAction,\n\tPaymentSetMethodInfoCustomTypeAction,\n\tPaymentSetMethodInfoInterfaceAccountAction,\n\tPaymentSetMethodInfoInterfaceAction,\n\tPaymentSetMethodInfoMethodAction,\n\tPaymentSetMethodInfoNameAction,\n\tPaymentSetMethodInfoTokenAction,\n\tPaymentSetStatusInterfaceCodeAction,\n\tPaymentSetStatusInterfaceTextAction,\n\tPaymentSetTransactionCustomFieldAction,\n\tPaymentSetTransactionCustomTypeAction,\n\tPaymentTransitionStateAction,\n\tPaymentUpdateAction,\n\tState,\n\tTransaction,\n} from \"@commercetools/platform-sdk\";\nimport type { Writable } from \"#src/types.ts\";\nimport type { RepositoryContext, UpdateHandlerInterface } from \"../abstract.ts\";\nimport { AbstractUpdateHandler } from \"../abstract.ts\";\nimport {\n\tcreateCentPrecisionMoney,\n\tcreateCustomFields,\n\tgetReferenceFromResourceIdentifier,\n} from \"../helpers.ts\";\nimport { transactionFromTransactionDraft } from \"./helpers.ts\";\n\nexport class PaymentUpdateHandler\n\textends AbstractUpdateHandler\n\timplements UpdateHandlerInterface<Payment, PaymentUpdateAction>\n{\n\taddInterfaceInteraction(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Payment>,\n\t\t{ type, fields }: PaymentAddInterfaceInteractionAction,\n\t) {\n\t\tresource.interfaceInteractions.push(\n\t\t\tcreateCustomFields({ type, fields }, context.projectKey, this._storage)!,\n\t\t);\n\t}\n\n\taddTransaction(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Payment>,\n\t\t{ transaction }: PaymentAddTransactionAction,\n\t) {\n\t\tresource.transactions = [\n\t\t\t...resource.transactions,\n\t\t\ttransactionFromTransactionDraft(context, this._storage, transaction),\n\t\t];\n\t}\n\n\tchangeAmountPlanned(\n\t\t_context: RepositoryContext,\n\t\tresource: Writable<Payment>,\n\t\t{ amount }: PaymentChangeAmountPlannedAction,\n\t) {\n\t\tresource.amountPlanned = createCentPrecisionMoney(amount);\n\t}\n\n\tchangeTransactionInteractionId(\n\t\t_context: RepositoryContext,\n\t\tresource: Writable<Payment>,\n\t\t{\n\t\t\ttransactionId,\n\t\t\tinteractionId,\n\t\t}: PaymentChangeTransactionInteractionIdAction,\n\t) {\n\t\tconst transaction = resource.transactions.find(\n\t\t\t(e: Transaction) => e.id === transactionId,\n\t\t);\n\t\tif (transaction) {\n\t\t\ttransaction.interactionId = interactionId;\n\t\t}\n\t}\n\n\tchangeTransactionState(\n\t\t_context: RepositoryContext,\n\t\tresource: Writable<Payment>,\n\t\t{ transactionId, state }: PaymentChangeTransactionStateAction,\n\t) {\n\t\tconst index = resource.transactions.findIndex(\n\t\t\t(e: Transaction) => e.id === transactionId,\n\t\t);\n\t\tconst updatedTransaction: Transaction = {\n\t\t\t...resource.transactions[index],\n\t\t\tstate,\n\t\t};\n\t\tresource.transactions[index] = updatedTransaction;\n\t}\n\n\tchangeTransactionTimestamp(\n\t\t_context: RepositoryContext,\n\t\tresource: Writable<Payment>,\n\t\t{ transactionId, timestamp }: PaymentChangeTransactionTimestampAction,\n\t) {\n\t\tconst transaction = resource.transactions.find(\n\t\t\t(e: Transaction) => e.id === transactionId,\n\t\t);\n\t\tif (transaction) {\n\t\t\ttransaction.timestamp = timestamp;\n\t\t}\n\t}\n\n\tsetAnonymousId(\n\t\t_context: RepositoryContext,\n\t\tresource: Writable<Payment>,\n\t\t{ anonymousId }: PaymentSetAnonymousIdAction,\n\t) {\n\t\tresource.anonymousId = anonymousId;\n\t\tresource.customer = undefined;\n\t}\n\n\tsetCustomer(\n\t\t_context: RepositoryContext,\n\t\tresource: Writable<Payment>,\n\t\t{ customer }: PaymentSetCustomerAction,\n\t) {\n\t\tif (customer) {\n\t\t\tconst c = getReferenceFromResourceIdentifier<CustomerReference>(\n\t\t\t\tcustomer,\n\t\t\t\t_context.projectKey,\n\t\t\t\tthis._storage,\n\t\t\t);\n\t\t\tresource.customer = c;\n\t\t\tresource.anonymousId = undefined;\n\t\t}\n\t}\n\n\tsetCustomField(\n\t\tcontext: RepositoryContext,\n\t\tresource: Payment,\n\t\t{ name, value }: PaymentSetCustomFieldAction,\n\t) {\n\t\tif (!resource.custom) {\n\t\t\tthrow new Error(\"Resource has no custom field\");\n\t\t}\n\n\t\tresource.custom.fields[name] = value;\n\t}\n\n\tsetCustomType(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Payment>,\n\t\t{ type, fields }: PaymentSetCustomTypeAction,\n\t) {\n\t\tif (!type) {\n\t\t\tresource.custom = undefined;\n\t\t} else {\n\t\t\tconst resolvedType = this._storage.getByResourceIdentifier(\n\t\t\t\tcontext.projectKey,\n\t\t\t\ttype,\n\t\t\t);\n\t\t\tif (!resolvedType) {\n\t\t\t\tthrow new Error(`Type ${type} not found`);\n\t\t\t}\n\n\t\t\tresource.custom = {\n\t\t\t\ttype: {\n\t\t\t\t\ttypeId: \"type\",\n\t\t\t\t\tid: resolvedType.id,\n\t\t\t\t},\n\t\t\t\tfields: fields ?? {},\n\t\t\t};\n\t\t}\n\t}\n\n\tsetInterfaceId(\n\t\t_context: RepositoryContext,\n\t\tresource: Writable<Payment>,\n\t\t{ interfaceId }: PaymentSetInterfaceIdAction,\n\t) {\n\t\tresource.interfaceId = interfaceId;\n\t}\n\n\tsetKey(\n\t\t_context: RepositoryContext,\n\t\tresource: Writable<Payment>,\n\t\t{ key }: PaymentSetKeyAction,\n\t) {\n\t\tresource.key = key;\n\t}\n\n\tsetMethodInfoInterface(\n\t\t_context: RepositoryContext,\n\t\tresource: Writable<Payment>,\n\t\targs: PaymentSetMethodInfoInterfaceAction,\n\t) {\n\t\tresource.paymentMethodInfo.paymentInterface = args.interface;\n\t}\n\n\tsetMethodInfoMethod(\n\t\t_context: RepositoryContext,\n\t\tresource: Writable<Payment>,\n\t\t{ method }: PaymentSetMethodInfoMethodAction,\n\t) {\n\t\tresource.paymentMethodInfo.method = method;\n\t}\n\n\tsetMethodInfoName(\n\t\t_context: RepositoryContext,\n\t\tresource: Writable<Payment>,\n\t\t{ name }: PaymentSetMethodInfoNameAction,\n\t) {\n\t\tresource.paymentMethodInfo.name = name;\n\t}\n\n\tsetStatusInterfaceCode(\n\t\t_context: RepositoryContext,\n\t\tresource: Writable<Payment>,\n\t\t{ interfaceCode }: PaymentSetStatusInterfaceCodeAction,\n\t) {\n\t\tresource.paymentStatus.interfaceCode = interfaceCode;\n\t}\n\n\tsetStatusInterfaceText(\n\t\t_context: RepositoryContext,\n\t\tresource: Writable<Payment>,\n\t\t{ interfaceText }: PaymentSetStatusInterfaceTextAction,\n\t) {\n\t\tresource.paymentStatus.interfaceText = interfaceText;\n\t}\n\n\tsetTransactionCustomField(\n\t\t_context: RepositoryContext,\n\t\tresource: Writable<Payment>,\n\t\t{ transactionId, name, value }: PaymentSetTransactionCustomFieldAction,\n\t) {\n\t\tconst transaction = resource.transactions.find(\n\t\t\t(e: Transaction) => e.id === transactionId,\n\t\t);\n\t\tif (transaction) {\n\t\t\tif (!transaction.custom) {\n\t\t\t\tthrow new Error(\"Transaction has no custom field\");\n\t\t\t}\n\n\t\t\ttransaction.custom.fields[name] = value;\n\t\t}\n\t}\n\n\tsetTransactionCustomType(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Payment>,\n\t\t{ transactionId, type, fields }: PaymentSetTransactionCustomTypeAction,\n\t) {\n\t\tconst transaction = resource.transactions.find(\n\t\t\t(e: Transaction) => e.id === transactionId,\n\t\t);\n\t\tif (transaction) {\n\t\t\tif (!type) {\n\t\t\t\ttransaction.custom = undefined;\n\t\t\t} else {\n\t\t\t\tconst resolvedType = this._storage.getByResourceIdentifier(\n\t\t\t\t\tcontext.projectKey,\n\t\t\t\t\ttype,\n\t\t\t\t);\n\t\t\t\tif (!resolvedType) {\n\t\t\t\t\tthrow new Error(`Type ${type} not found`);\n\t\t\t\t}\n\n\t\t\t\ttransaction.custom = {\n\t\t\t\t\ttype: {\n\t\t\t\t\t\ttypeId: \"type\",\n\t\t\t\t\t\tid: resolvedType.id,\n\t\t\t\t\t},\n\t\t\t\t\tfields: fields ?? {},\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\t}\n\n\ttransitionState(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Payment>,\n\t\t{ state }: PaymentTransitionStateAction,\n\t) {\n\t\tconst stateObj = this._storage.getByResourceIdentifier(\n\t\t\tcontext.projectKey,\n\t\t\tstate,\n\t\t) as State | null;\n\n\t\tif (!stateObj) {\n\t\t\tthrow new Error(`State ${state} not found`);\n\t\t}\n\n\t\tresource.paymentStatus.state = {\n\t\t\ttypeId: \"state\",\n\t\t\tid: stateObj.id,\n\t\t\tobj: stateObj,\n\t\t};\n\t}\n\n\tsetMethodInfo(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Payment>,\n\t\t{\n\t\t\tpaymentInterface,\n\t\t\tmethod,\n\t\t\tname,\n\t\t\tinterfaceAccount,\n\t\t\ttoken,\n\t\t}: PaymentSetMethodInfoAction,\n\t) {\n\t\tif (paymentInterface !== undefined) {\n\t\t\tresource.paymentMethodInfo.paymentInterface = paymentInterface;\n\t\t}\n\t\tif (method !== undefined) {\n\t\t\tresource.paymentMethodInfo.method = method;\n\t\t}\n\t\tif (name !== undefined) {\n\t\t\tresource.paymentMethodInfo.name = name;\n\t\t}\n\t\tif (interfaceAccount !== undefined) {\n\t\t\tresource.paymentMethodInfo.interfaceAccount = interfaceAccount;\n\t\t}\n\t\tif (token !== undefined) {\n\t\t\tresource.paymentMethodInfo.token = token;\n\t\t}\n\t}\n\n\tsetMethodInfoCustomField(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Payment>,\n\t\t{ name, value }: PaymentSetMethodInfoCustomFieldAction,\n\t) {\n\t\tif (!resource.paymentMethodInfo.custom) {\n\t\t\tthrow new Error(\"PaymentMethodInfo has no custom field\");\n\t\t}\n\n\t\tresource.paymentMethodInfo.custom.fields[name] = value;\n\t}\n\n\tsetMethodInfoCustomType(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Payment>,\n\t\t{ type, fields }: PaymentSetMethodInfoCustomTypeAction,\n\t) {\n\t\tif (!type) {\n\t\t\tresource.paymentMethodInfo.custom = undefined;\n\t\t} else {\n\t\t\tconst resolvedType = this._storage.getByResourceIdentifier(\n\t\t\t\tcontext.projectKey,\n\t\t\t\ttype,\n\t\t\t);\n\t\t\tif (!resolvedType) {\n\t\t\t\tthrow new Error(`Type ${type} not found`);\n\t\t\t}\n\n\t\t\tresource.paymentMethodInfo.custom = {\n\t\t\t\ttype: {\n\t\t\t\t\ttypeId: \"type\",\n\t\t\t\t\tid: resolvedType.id,\n\t\t\t\t},\n\t\t\t\tfields: fields ?? {},\n\t\t\t};\n\t\t}\n\t}\n\n\tsetMethodInfoInterfaceAccount(\n\t\t_context: RepositoryContext,\n\t\tresource: Writable<Payment>,\n\t\t{ interfaceAccount }: PaymentSetMethodInfoInterfaceAccountAction,\n\t) {\n\t\tresource.paymentMethodInfo.interfaceAccount = interfaceAccount;\n\t}\n\n\tsetMethodInfoToken(\n\t\t_context: RepositoryContext,\n\t\tresource: Writable<Payment>,\n\t\t{ token }: PaymentSetMethodInfoTokenAction,\n\t) {\n\t\tresource.paymentMethodInfo.token = token;\n\t}\n}\n","import type {\n\tPayment,\n\tPaymentDraft,\n\tStateReference,\n} from \"@commercetools/platform-sdk\";\nimport type { Config } from \"#src/config.ts\";\nimport { getBaseResourceProperties } from \"#src/helpers.ts\";\nimport type { RepositoryContext } from \"../abstract.ts\";\nimport { AbstractResourceRepository } from \"../abstract.ts\";\nimport {\n\tcreateCentPrecisionMoney,\n\tcreateCustomFields,\n\tgetReferenceFromResourceIdentifier,\n} from \"../helpers.ts\";\nimport { PaymentUpdateHandler } from \"./actions.ts\";\nimport { transactionFromTransactionDraft } from \"./helpers.ts\";\n\nexport class PaymentRepository extends AbstractResourceRepository<\"payment\"> {\n\tconstructor(config: Config) {\n\t\tsuper(\"payment\", config);\n\t\tthis.actions = new PaymentUpdateHandler(this._storage);\n\t}\n\n\tcreate(context: RepositoryContext, draft: PaymentDraft): Payment {\n\t\tconst resource: Payment = {\n\t\t\t...getBaseResourceProperties(),\n\t\t\tkey: draft.key,\n\t\t\tamountPlanned: createCentPrecisionMoney(draft.amountPlanned),\n\t\t\tpaymentMethodInfo: { ...draft.paymentMethodInfo!, custom: undefined },\n\t\t\tpaymentStatus: draft.paymentStatus\n\t\t\t\t? {\n\t\t\t\t\t\t...draft.paymentStatus,\n\t\t\t\t\t\tstate: draft.paymentStatus.state\n\t\t\t\t\t\t\t? getReferenceFromResourceIdentifier<StateReference>(\n\t\t\t\t\t\t\t\t\tdraft.paymentStatus.state,\n\t\t\t\t\t\t\t\t\tcontext.projectKey,\n\t\t\t\t\t\t\t\t\tthis._storage,\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t: undefined,\n\t\t\t\t\t}\n\t\t\t\t: {},\n\t\t\ttransactions: (draft.transactions || []).map((t) =>\n\t\t\t\ttransactionFromTransactionDraft(context, this._storage, t),\n\t\t\t),\n\t\t\tinterfaceInteractions: (draft.interfaceInteractions || []).map(\n\t\t\t\t(interaction) =>\n\t\t\t\t\tcreateCustomFields(interaction, context.projectKey, this._storage)!,\n\t\t\t),\n\t\t\tcustom: createCustomFields(\n\t\t\t\tdraft.custom,\n\t\t\t\tcontext.projectKey,\n\t\t\t\tthis._storage,\n\t\t\t),\n\t\t};\n\n\t\treturn this.saveNew(context, resource);\n\t}\n}\n","import type {\n\tReview,\n\tReviewRatingStatistics,\n} from \"@commercetools/platform-sdk\";\nimport type { AbstractStorage } from \"../storage/index.ts\";\n\nexport class ReviewStatisticsService {\n\tconstructor(private _storage: AbstractStorage) {}\n\n\tcalculateProductReviewStatistics(\n\t\tprojectKey: string,\n\t\tproductId: string,\n\t): ReviewRatingStatistics | undefined {\n\t\t// Get all reviews for this product\n\t\tconst allReviews = this._storage.all(projectKey, \"review\") as Review[];\n\t\tconst productReviews = allReviews.filter(\n\t\t\t(review) =>\n\t\t\t\treview.target?.typeId === \"product\" &&\n\t\t\t\treview.target?.id === productId &&\n\t\t\t\treview.includedInStatistics &&\n\t\t\t\treview.rating !== undefined,\n\t\t);\n\n\t\tif (productReviews.length === 0) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst ratings = productReviews\n\t\t\t.map((review) => review.rating!)\n\t\t\t.filter((rating) => rating !== undefined);\n\n\t\tif (ratings.length === 0) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\t// Calculate statistics\n\t\tconst count = ratings.length;\n\t\tconst sum = ratings.reduce((acc, rating) => acc + rating, 0);\n\t\tconst averageRating = Math.round((sum / count) * 100000) / 100000; // Round to 5 decimals\n\t\tconst highestRating = Math.max(...ratings);\n\t\tconst lowestRating = Math.min(...ratings);\n\n\t\t// Calculate ratings distribution\n\t\tconst ratingsDistribution: { [key: string]: number } = {};\n\t\tfor (const rating of ratings) {\n\t\t\tconst key = rating.toString();\n\t\t\tratingsDistribution[key] = (ratingsDistribution[key] || 0) + 1;\n\t\t}\n\n\t\treturn {\n\t\t\taverageRating,\n\t\t\thighestRating,\n\t\t\tlowestRating,\n\t\t\tcount,\n\t\t\tratingsDistribution,\n\t\t};\n\t}\n}\n","import TokenTypes from \"./token-types\";\n\n/**\n * @private\n */\nexport default class LexerState<T> {\n\tpublic source: string;\n\tpublic position: number;\n\tpublic tokenTypes: TokenTypes<T>;\n\n\tconstructor(source: string, position: number = 0) {\n\t\tthis.source = source;\n\t\tthis.position = position;\n\t}\n\n\tcopy() {\n\t\treturn new LexerState<T>(this.source, this.position);\n\t}\n}\n","import Lexer from \"./lexer\";\n\n/**\n * @typedef {{\n * start: Position,\n * end: Position,\n * }} TokenPosition\n */\n\n/**\n * Represents a token instance\n */\nclass Token<T> {\n\ttype: T;\n\n\tmatch: string;\n\n\tgroups: string[];\n\n\tstart: number;\n\n\tend: number;\n\n\tlexer: Lexer<T>;\n\n\t/* tslint:disable:indent */\n\t/**\n\t * Constructs a token\n\t * @param {T} type The token type\n\t * @param {string} match The string that the lexer consumed to create this token\n\t * @param {string[]} groups Any RegExp groups that accrued during the match\n\t * @param {number} start The string position where this match started\n\t * @param {number} end The string position where this match ends\n\t * @param {Lexer<T>} lexer The parent {@link Lexer}\n\t */\n\tconstructor(\n\t\ttype: T,\n\t\tmatch: string,\n\t\tgroups: string[],\n\t\tstart: number,\n\t\tend: number,\n\t\tlexer: Lexer<T>,\n\t) {\n\t\t/* tslint:enable */\n\t\t/**\n\t\t * The token type\n\t\t * @type {T}\n\t\t */\n\t\tthis.type = type;\n\n\t\t/**\n\t\t * The string that the lexer consumed to create this token\n\t\t * @type {string}\n\t\t */\n\t\tthis.match = match;\n\n\t\t/**\n\t\t * Any RegExp groups that accrued during the match\n\t\t * @type {string[]}\n\t\t */\n\t\tthis.groups = groups;\n\n\t\t/**\n\t\t * The string position where this match started\n\t\t * @type {number}\n\t\t */\n\t\tthis.start = start;\n\n\t\t/**\n\t\t * The string position where this match ends\n\t\t * @type {number}\n\t\t */\n\t\tthis.end = end;\n\n\t\t/**\n\t\t * The parent {@link Lexer}\n\t\t * @type {Lexer<T>}\n\t\t */\n\t\tthis.lexer = lexer;\n\t}\n\n\t/**\n\t * Returns the bounds of this token, each in `{line, column}` format\n\t * @return {TokenPosition}\n\t */\n\tstrpos() {\n\t\tconst start = this.lexer.strpos(this.start);\n\t\tconst end = this.lexer.strpos(this.end);\n\t\treturn { start, end };\n\t}\n\n\t// tslint:disable-next-line prefer-function-over-method\n\tisEof() {\n\t\treturn false;\n\t}\n}\n\nexport default Token;\n\nexport class EOFToken<T> extends Token<T> {\n\tconstructor(lexer: Lexer<T>) {\n\t\tconst end = lexer.source.length;\n\t\tsuper(null as T, \"(eof)\", [], end, end, lexer);\n\t}\n\n\t// tslint:disable-next-line prefer-function-over-method\n\tisEof() {\n\t\treturn true;\n\t}\n}\n\n/**\n * @private\n */\nexport const EOF = (lexer: Lexer<any>) => new EOFToken(lexer);\n","// Thank you, http://stackoverflow.com/a/6969486\nfunction toRegExp(str: string): RegExp {\n\treturn new RegExp(str.replace(/[\\-\\[\\]\\/\\{\\}\\(\\)\\*\\+\\?\\.\\\\\\^\\$\\|]/g, \"\\\\$&\"));\n}\n\nfunction normalize(regex: RegExp | string): RegExp {\n\tif (typeof regex === \"string\") regex = toRegExp(regex);\n\tif (!regex.source.startsWith(\"^\"))\n\t\treturn new RegExp(`^${regex.source}`, regex.flags);\n\telse return regex;\n}\n\nfunction first<T, U>(\n\tarr: T[],\n\tpredicate: (item: T, i: number) => U,\n): { item: T; result: U } | undefined {\n\tlet i = 0;\n\tfor (const item of arr) {\n\t\tconst result = predicate(item, i++);\n\t\tif (result) return { item, result };\n\t}\n}\n\n/**\n * @private\n */\nexport default class TokenTypes<T> {\n\tpublic tokenTypes: {\n\t\ttype: T;\n\t\tregex: RegExp;\n\t\tenabled: boolean;\n\t\tskip: boolean;\n\t}[];\n\n\tconstructor() {\n\t\tthis.tokenTypes = [];\n\t}\n\n\tdisable(type: T): TokenTypes<T> {\n\t\treturn this.enable(type, false);\n\t}\n\n\tenable(type: T, enabled: boolean = true): TokenTypes<T> {\n\t\tthis.tokenTypes\n\t\t\t.filter((t) => t.type == type)\n\t\t\t.forEach((t) => (t.enabled = enabled));\n\t\treturn this;\n\t}\n\n\tisEnabled(type: T) {\n\t\tconst ttypes = this.tokenTypes.filter((tt) => tt.type == type);\n\t\tif (ttypes.length == 0)\n\t\t\tthrow new Error(`Token of type ${type} does not exists`);\n\t\treturn ttypes[0].enabled;\n\t}\n\n\tpeek(source: string, position: number) {\n\t\tconst s = source.substr(position);\n\t\treturn first(\n\t\t\tthis.tokenTypes.filter((tt) => tt.enabled),\n\t\t\t(tt) => {\n\t\t\t\ttt.regex.lastIndex = 0;\n\t\t\t\treturn tt.regex.exec(s);\n\t\t\t},\n\t\t);\n\t}\n\n\ttoken(\n\t\ttype: T,\n\t\tpattern: RegExp | string,\n\t\tskip: boolean = false,\n\t): TokenTypes<T> {\n\t\tthis.tokenTypes.push({\n\t\t\ttype,\n\t\t\tregex: normalize(pattern),\n\t\t\tenabled: true,\n\t\t\tskip,\n\t\t});\n\t\treturn this;\n\t}\n}\n","import LexerState from \"./lexer-state\";\nimport Token, { EOF } from \"./token\";\nimport TokenTypes from \"./token-types\";\n\n/**\n * @typedef {{\n * line: number,\n * column: number,\n * }} Position\n */\n\n/**\n * Lexes a source-string into tokens.\n *\n * @example\n * const lex = perplex('...')\n * .token('ID', /my-id-regex/)\n * .token('(', /\\(/)\n * .token(')', /\\)/)\n * .token('WS', /\\s+/, true) // true means 'skip'\n *\n * while ((let t = lex.next()).type != 'EOF') {\n * console.log(t)\n * }\n * // alternatively:\n * console.log(lex.toArray())\n * // or:\n * console.log(...lex)\n */\nclass Lexer<T> implements Iterable<Token<T>> {\n\t/* tslint:disable:variable-name */\n\tprivate _state: LexerState<T>;\n\n\tprivate _tokenTypes: TokenTypes<T>;\n\t/* tslint:enable */\n\n\t/**\n\t * Creates a new Lexer instance\n\t * @param {string} [source = ''] The source string to operate on.\n\t */\n\tconstructor(source: string = \"\") {\n\t\tthis._state = new LexerState<T>(source);\n\t\tthis._tokenTypes = new TokenTypes<T>();\n\t}\n\n\t//\n\t// Getters/Setters\n\t//\n\n\t/**\n\t * Gets the current lexer position\n\t * @return {number} Returns the position\n\t */\n\tget position() {\n\t\treturn this._state.position;\n\t}\n\n\t/**\n\t * Sets the current lexer position\n\t * @param {number} i The position to move to\n\t */\n\tset position(i: number) {\n\t\tthis._state.position = i;\n\t}\n\n\t/**\n\t * Gets the source the lexer is operating on\n\t * @return {string} Returns the source\n\t */\n\tget source() {\n\t\treturn this._state.source;\n\t}\n\n\t/**\n\t * Sets the source the lexer is operating on\n\t * @param {string} s The source to set\n\t */\n\tset source(s: string) {\n\t\tthis._state = new LexerState<T>(s);\n\t}\n\n\t//\n\t// METHODS\n\t//\n\n\t/**\n\t * Attaches this lexer to another lexer's state\n\t * @param {Lexer<T>} other The other lexer to attach to\n\t */\n\tattachTo(other: Lexer<T>) {\n\t\tthis._state = other._state;\n\t}\n\n\t/**\n\t * Disables a token type\n\t * @param {T} type The token type to disable\n\t * @return {Lexer<T>}\n\t */\n\tdisable(type: T) {\n\t\tthis._tokenTypes.disable(type);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Enables a token type\n\t * @param {T} type The token type to enalbe\n\t * @param {?boolean} [enabled=true] Whether to enable/disable the specified token type\n\t * @return {Lexer<T>}\n\t */\n\tenable(type: T, enabled?: boolean) {\n\t\tthis._tokenTypes.enable(type, enabled);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Like {@link next}, but throws an exception if the next token is\n\t * not of the required type.\n\t * @param {T} type The token type expected from {@link next}\n\t * @return {Token<T>} Returns the {@link Token} on success\n\t */\n\texpect(type: T): Token<T> {\n\t\tconst t = this.next();\n\t\tif (t.type != type) {\n\t\t\tconst pos = t.strpos();\n\t\t\tthrow new Error(\n\t\t\t\t\"Expected \" +\n\t\t\t\t\ttype +\n\t\t\t\t\t(t ? \", got \" + t.type : \"\") +\n\t\t\t\t\t\" at \" +\n\t\t\t\t\tpos.start.line +\n\t\t\t\t\t\":\" +\n\t\t\t\t\tpos.start.column,\n\t\t\t);\n\t\t}\n\t\treturn t;\n\t}\n\n\t/**\n\t * Looks up whether a token is enabled.\n\t * @param tokenType The token type to look up\n\t * @return {boolean} Returns whether the token is enabled\n\t */\n\tisEnabled(tokenType: T) {\n\t\treturn this._tokenTypes.isEnabled(tokenType);\n\t}\n\n\t/**\n\t * Consumes and returns the next {@link Token} in the source string.\n\t * If there are no more tokens, it returns a {@link Token} of type `$EOF`\n\t * @return {Token<T>}\n\t */\n\tnext(): Token<T> {\n\t\ttry {\n\t\t\tconst t = this.peek();\n\t\t\tthis._state.position = t.end;\n\t\t\treturn t;\n\t\t} catch (e) {\n\t\t\tthis._state.position = (e as any).end;\n\t\t\tthrow e;\n\t\t}\n\t}\n\n\t/**\n\t * Returns the next {@link Token} in the source string, but does\n\t * not consume it.\n\t * If there are no more tokens, it returns a {@link Token} of type `$EOF`\n\t * @param {number} [position=`this.position`] The position at which to start reading\n\t * @return {Token<T>}\n\t */\n\tpeek(position: number = this._state.position): Token<T> {\n\t\tconst read = (i: number = position): Token<T> | null => {\n\t\t\tif (i >= this._state.source.length) return EOF(this);\n\t\t\tconst n = this._tokenTypes.peek(this._state.source, i);\n\t\t\tif (!n || !n.result) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Unexpected input: ${this._state.source.substring(\n\t\t\t\t\t\ti,\n\t\t\t\t\t\ti + 1,\n\t\t\t\t\t)} at (${this.strpos(i).line}:${this.strpos(i).column})`,\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn n\n\t\t\t\t? n.item.skip\n\t\t\t\t\t? read(i + n.result[0].length)\n\t\t\t\t\t: new Token(\n\t\t\t\t\t\t\tn.item.type,\n\t\t\t\t\t\t\tn.result[0],\n\t\t\t\t\t\t\tn.result.map((x) => x),\n\t\t\t\t\t\t\ti,\n\t\t\t\t\t\t\ti + n.result[0].length,\n\t\t\t\t\t\t\tthis,\n\t\t\t\t\t\t)\n\t\t\t\t: null;\n\t\t};\n\t\tconst t = read();\n\t\tif (t) return t;\n\n\t\t// we did not find a match\n\t\tlet unexpected = this._state.source.substring(position, position + 1);\n\t\ttry {\n\t\t\tthis.peek(position + 1);\n\t\t} catch (e) {\n\t\t\tunexpected += (e as any).unexpected;\n\t\t}\n\t\tconst { line, column } = this.strpos(position);\n\t\tconst e = new Error(\n\t\t\t`Unexpected input: ${unexpected} at (${line}:${column})`,\n\t\t);\n\t\t(e as any).unexpected = unexpected;\n\t\t(e as any).end = position + unexpected.length;\n\t\tthrow e;\n\t}\n\n\t/**\n\t * Converts a string-index (relative to the source string) to a line and a column.\n\t * @param {number} i The index to compute\n\t * @return {Position}\n\t */\n\tstrpos(i: number): {\n\t\tline: number;\n\t\tcolumn: number;\n\t} {\n\t\tlet lines = this._state.source.substring(0, i).split(/\\r?\\n/);\n\t\tif (!Array.isArray(lines)) lines = [lines];\n\n\t\tconst line = lines.length;\n\t\tconst column = lines[lines.length - 1].length + 1;\n\t\treturn { line, column };\n\t}\n\n\t/**\n\t * Converts the token stream to an array of Tokens\n\t * @return {Token<T>[]} The array of tokens (not including (EOF))\n\t */\n\ttoArray(): Token<T>[] {\n\t\treturn [...this];\n\t}\n\n\t/**\n\t * Implements the Iterable protocol\n\t * Iterates lazily over the entire token stream (not including (EOF))\n\t * @return {Iterator<Token<T>>} Returns an iterator over all remaining tokens\n\t */\n\t*[Symbol.iterator]() {\n\t\tconst oldState = this._state.copy();\n\t\tthis._state.position = 0;\n\n\t\tlet t;\n\t\twhile (\n\t\t\t!(t = this.next()).isEof() // tslint:disable-line no-conditional-assignment\n\t\t)\n\t\t\tyield t;\n\n\t\tthis._state = oldState;\n\t}\n\n\t/**\n\t * Creates a new token type\n\t * @param {T} type The token type\n\t * @param {string|RegExp} pattern The pattern to match\n\t * @param {?boolean} skip Whether this type of token should be skipped\n\t * @return {Lexer<T>}\n\t */\n\ttoken(type: T, pattern: string | RegExp, skip?: boolean) {\n\t\tthis._tokenTypes.token(type, pattern, skip);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Creates a keyword\n\t * @param kwd The keyword to add as a token\n\t */\n\tkeyword(kwd: T) {\n\t\treturn this.token(kwd, new RegExp(`${kwd}(?=\\\\W|$)`));\n\t}\n\n\t/**\n\t * Creates an operator\n\t * @param op The operator to add as a token\n\t */\n\toperator(op: T) {\n\t\tconst sOp = new String(op).valueOf();\n\t\treturn this.token(op, sOp);\n\t}\n}\n\nexport default Lexer;\nexport { EOF, Lexer, LexerState, Token, TokenTypes };\n","// From https://github.com/jrop/pratt/blob/master/src/index.ts\n\nexport interface IPosition {\n\tline: number;\n\tcolumn: number;\n}\nexport interface ITokenPosition {\n\tstart: IPosition;\n\tend: IPosition;\n}\nexport interface IToken<T> {\n\ttype: T;\n\tmatch: string;\n\tstrpos(): ITokenPosition;\n\tisEof(): boolean;\n}\nexport interface ILexer<T> {\n\tnext(): IToken<T>;\n\tpeek(): IToken<T>;\n}\n\nexport type BPResolver = () => number;\nexport type BP = number | BPResolver;\n\nexport type StopFunction = (<T>(x: T) => T) & { isStopped(): boolean };\n\nexport type NudInfo<T> = {\n\ttoken: IToken<T>;\n\tbp: number;\n\tstop: StopFunction;\n\n\t// TODO: with the below addition of `options`\n\t// the `ctx parameter is carried through anyway\n\t// remove in a breaking API change release\n\tctx: any;\n\toptions: ParseOpts<T>;\n};\nexport type LedInfo<T> = NudInfo<T> & { left: any };\n\nexport type NudFunction<T> = (inf: NudInfo<T>) => any;\nexport type LedFunction<T> = (inf: LedInfo<T>) => any;\n\nexport type NudMap<T> = Map<T, NudFunction<T>>;\nexport type LedMap<T> = Map<T, LedFunction<T>>;\n\nexport type ParseOpts<T> = {\n\tctx?: any;\n\tstop?: StopFunction;\n\tterminals?: (number | T)[];\n};\n\nconst createStop = <T>(): StopFunction => {\n\tlet stopCalled = false;\n\treturn Object.assign(\n\t\t(x: T) => {\n\t\t\tstopCalled = true;\n\t\t\treturn x;\n\t\t},\n\t\t{\n\t\t\tisStopped() {\n\t\t\t\treturn stopCalled;\n\t\t\t},\n\t\t},\n\t) as StopFunction;\n};\n\n/**\n * A Pratt parser.\n * @example\n * const lex = new perplex.Lexer('1 + -2 * 3^4')\n * .token('NUM', /\\d+/)\n * .token('+', /\\+/)\n * .token('-', /-/)\n * .token('*', new RegExp('*'))\n * .token('/', /\\//)\n * .token('^', /\\^/)\n * .token('(', /\\(/)\n * .token(')', /\\)/)\n * .token('$SKIP_WS', /\\s+/)\n *\n * const parser = new Parser(lex)\n * .builder()\n * .nud('NUM', 100, t => parseInt(t.match))\n * .nud('-', 10, (t, bp) => -parser.parse(bp))\n * .nud('(', 10, (t, bp) => {\n * const expr = parser.parse(bp)\n * lex.expect(')')\n * return expr\n * })\n * .bp(')', 0)\n *\n * .led('^', 20, (left, t, bp) => Math.pow(left, parser.parse(20 - 1)))\n * .led('+', 30, (left, t, bp) => left + parser.parse(bp))\n * .led('-', 30, (left, t, bp) => left - parser.parse(bp))\n * .led('*', 40, (left, t, bp) => left * parser.parse(bp))\n * .led('/', 40, (left, t, bp) => left / parser.parse(bp))\n * .build()\n * parser.parse()\n * // => 161\n */\nexport class Parser<T> {\n\tpublic lexer: ILexer<T>;\n\t_nuds: NudMap<T>;\n\t_leds: LedMap<T>;\n\t_bps: Map<T, BP>;\n\n\t/**\n\t * Constructs a Parser instance\n\t * @param {ILexer<T>} lexer The lexer to obtain tokens from\n\t */\n\tconstructor(lexer: ILexer<T>) {\n\t\t/**\n\t\t * The lexer that this parser is operating on.\n\t\t * @type {ILexer<T>}\n\t\t */\n\t\tthis.lexer = lexer;\n\t\tthis._nuds = new Map();\n\t\tthis._leds = new Map();\n\t\tthis._bps = new Map();\n\t}\n\n\tprivate _type(tokenOrType: IToken<T> | T): T {\n\t\treturn tokenOrType && typeof (tokenOrType as IToken<T>).isEof == \"function\"\n\t\t\t? (tokenOrType as IToken<T>).type\n\t\t\t: (tokenOrType as T);\n\t}\n\n\t/**\n\t * Create a {@link ParserBuilder}\n\t * @return {ParserBuilder<T>} Returns the ParserBuilder\n\t */\n\tbuilder(): ParserBuilder<T> {\n\t\treturn new ParserBuilder(this);\n\t}\n\n\t/**\n\t * Define binding power for a token-type\n\t * @param {IToken<T>|T} tokenOrType The token type to define the binding power for\n\t * @returns {number} The binding power of the specified token type\n\t */\n\tbp(tokenOrType: IToken<T> | T) {\n\t\tif (tokenOrType == null) return Number.NEGATIVE_INFINITY;\n\t\tif (\n\t\t\ttokenOrType &&\n\t\t\ttypeof (tokenOrType as IToken<T>).isEof == \"function\" &&\n\t\t\t(tokenOrType as IToken<T>).isEof()\n\t\t)\n\t\t\treturn Number.NEGATIVE_INFINITY;\n\t\tconst type = this._type(tokenOrType);\n\t\tconst bp = this._bps.has(type)\n\t\t\t? this._bps.get(type)\n\t\t\t: Number.POSITIVE_INFINITY;\n\t\treturn typeof bp == \"function\" ? bp() : bp;\n\t}\n\n\t/**\n\t * Computes the token's `nud` value and returns it\n\t * @param {NudInfo<T>} info The info to compute the `nud` from\n\t * @returns {any} The result of invoking the pertinent `nud` operator\n\t */\n\tnud(info: NudInfo<T>) {\n\t\tconst fn: NudFunction<T> | undefined = this._nuds.get(info.token.type);\n\t\tif (!fn) {\n\t\t\tconst { start } = info.token.strpos();\n\t\t\tthrow new Error(\n\t\t\t\t`Unexpected token: ${info.token.match} (at ${start.line}:${start.column})`,\n\t\t\t);\n\t\t}\n\t\treturn fn(info);\n\t}\n\n\t/**\n\t * Computes a token's `led` value and returns it\n\t * @param {LedInfo<T>} info The info to compute the `led` value for\n\t * @returns {any} The result of invoking the pertinent `led` operator\n\t */\n\tled(info: LedInfo<T>) {\n\t\tlet fn = this._leds.get(info.token.type);\n\t\tif (!fn) {\n\t\t\tconst { start } = info.token.strpos();\n\t\t\tthrow new Error(\n\t\t\t\t`Unexpected token: ${info.token.match} (at ${start.line}:${start.column})`,\n\t\t\t);\n\t\t}\n\t\treturn fn(info);\n\t}\n\n\t/**\n\t * Kicks off the Pratt parser, and returns the result\n\t * @param {ParseOpts<T>} opts The parse options\n\t * @returns {any}\n\t */\n\tparse(opts: ParseOpts<T> = { terminals: [0] }): any {\n\t\tconst stop = (opts.stop = opts.stop || createStop());\n\t\tconst check = () => {\n\t\t\tif (stop.isStopped()) return false;\n\t\t\tconst t = this.lexer.peek();\n\t\t\tconst bp = this.bp(t);\n\n\t\t\t// @ts-ignore\n\t\t\treturn opts.terminals.reduce((canContinue, rbpOrType) => {\n\t\t\t\tif (!canContinue) return false;\n\t\t\t\t// @ts-ignore\n\t\t\t\tif (typeof rbpOrType == \"number\") return rbpOrType < bp;\n\t\t\t\tif (typeof rbpOrType == \"string\") return t.type != rbpOrType;\n\t\t\t}, true);\n\t\t};\n\t\tconst mkinfo = (token: IToken<T>): NudInfo<T> => {\n\t\t\tconst bp = this.bp(token);\n\t\t\t// @ts-ignore\n\t\t\treturn { token, bp, stop, ctx: opts.ctx, options: opts };\n\t\t};\n\t\tif (!opts.terminals) opts.terminals = [0];\n\t\tif (opts.terminals.length == 0) opts.terminals.push(0);\n\n\t\tlet left = this.nud(mkinfo(this.lexer.next()));\n\t\twhile (check()) {\n\t\t\tconst operator = this.lexer.next();\n\t\t\tleft = this.led(Object.assign(mkinfo(operator), { left }));\n\t\t}\n\t\treturn left;\n\t}\n}\n\n/**\n * Builds `led`/`nud` rules for a {@link Parser}\n */\nexport class ParserBuilder<T> {\n\tprivate _parser: Parser<T>;\n\n\t/**\n\t * Constructs a ParserBuilder\n\t * See also: {@link Parser.builder}\n\t * @param {Parser<T>} parser The parser\n\t */\n\tconstructor(parser: Parser<T>) {\n\t\tthis._parser = parser;\n\t}\n\n\t/**\n\t * Define `nud` for a token type\n\t * @param {T} tokenType The token type\n\t * @param {number} bp The binding power\n\t * @param {NudFunction<T>} fn The function that will parse the token\n\t * @return {ParserBuilder<T>} Returns this ParserBuilder\n\t */\n\tnud(tokenType: T, bp: BP, fn: NudFunction<T>): ParserBuilder<T> {\n\t\tthis._parser._nuds.set(tokenType, fn);\n\t\tthis.bp(tokenType, bp);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Define `led` for a token type\n\t * @param {T} tokenType The token type\n\t * @param {number} bp The binding power\n\t * @param {LedFunction<T>} fn The function that will parse the token\n\t * @return {ParserBuilder<T>} Returns this ParserBuilder\n\t */\n\tled(tokenType: T, bp: BP, fn: LedFunction<T>): ParserBuilder<T> {\n\t\tthis._parser._leds.set(tokenType, fn);\n\t\tthis.bp(tokenType, bp);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Define both `led` and `nud` for a token type at once.\n\t * The supplied `LedFunction` may be called with a null `left`\n\t * parameter when invoked from a `nud` context.\n\t * @param {strTng} tokenType The token type\n\t * @param {number} bp The binding power\n\t * @param {LedFunction<T>} fn The function that will parse the token\n\t * @return {ParserBuilder<T>} Returns this ParserBuilder\n\t */\n\teither(tokenType: T, bp: BP, fn: LedFunction<T>): ParserBuilder<T> {\n\t\treturn this.nud(tokenType, bp, (inf) =>\n\t\t\tfn(Object.assign(inf, { left: null })),\n\t\t).led(tokenType, bp, fn);\n\t}\n\n\t/**\n\t * Define the binding power for a token type\n\t * @param {T} tokenType The token type\n\t * @param {BP} bp The binding power\n\t * @return {ParserBuilder<T>} Returns this ParserBuilder\n\t */\n\tbp(tokenType: T, bp: BP): ParserBuilder<T> {\n\t\tthis._parser._bps.set(tokenType, bp);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Returns the parent {@link Parser} instance\n\t * @returns {Parser<T>}\n\t */\n\tbuild(): Parser<T> {\n\t\treturn this._parser;\n\t}\n}\n","/**\n * This module implements the commercetools product projection filter expression.\n */\n\nimport type {\n\tProductProjection,\n\tProductVariant,\n} from \"@commercetools/platform-sdk\";\nimport { nestedLookup } from \"../helpers.ts\";\nimport type { Writable } from \"../types.ts\";\nimport { Lexer, Parser } from \"./parser.ts\";\n\ntype MatchFunc = (target: any) => boolean;\n\ntype ProductProjectionFilter = (\n\tp: Writable<ProductProjection>,\n\tmarkMatchingVariants: boolean,\n) => boolean;\n\ntype TypeSymbol = {\n\ttype: \"Symbol\";\n\tkind: \"int\" | \"string\" | \"any\";\n\tvalue: any;\n};\n\ntype RangeExpressionSet = {\n\tsource: string;\n\ttype: \"RangeExpression\";\n\tchildren?: RangeExpression[];\n};\n\ntype FilterExpressionSet = {\n\tsource: string;\n\ttype: \"FilterExpression\";\n\tchildren?: FilterExpression[];\n};\n\ntype TermExpressionSet = {\n\tsource: string;\n\ttype: \"TermExpression\";\n};\n\ntype ExpressionSet =\n\t| RangeExpressionSet\n\t| FilterExpressionSet\n\t| TermExpressionSet;\n\nexport type RangeExpression = {\n\ttype: \"RangeExpression\";\n\tstart?: number;\n\tstop?: number;\n\tmatch: (obj: any) => boolean;\n};\n\nexport type FilterExpression = {\n\ttype: \"FilterExpression\";\n\tmatch: (obj: any) => boolean;\n};\n\n/**\n * Returns a function (ProductProjectionFilter).\n * NOTE: The filter can alter the resources in-place (FIXME)\n */\nexport const parseFilterExpression = (\n\tfilter: string,\n): ProductProjectionFilter => {\n\tconst exprFunc = generateMatchFunc(filter);\n\tconst [source] = filter.split(\":\", 1);\n\n\tif (source.startsWith(\"variants.\")) {\n\t\treturn filterVariants(source, exprFunc);\n\t}\n\treturn filterProduct(source, exprFunc);\n};\n\nconst getLexer = (value: string) =>\n\tnew Lexer(value)\n\t\t.token(\"MISSING\", /missing(?![-_a-z0-9]+)/i)\n\t\t.token(\"EXISTS\", /exists(?![-_a-z0-9]+)/i)\n\t\t.token(\"RANGE\", /range(?![-_a-z0-9]+)/i)\n\t\t.token(\"TO\", /to(?![-_a-z0-9]+)/i)\n\t\t.token(\"IDENTIFIER\", /[-_.a-z]+/i)\n\n\t\t.token(\"FLOAT\", /\\d+\\.\\d+/)\n\t\t.token(\"INT\", /\\d+/)\n\t\t.token(\"STRING\", /\"((?:\\\\.|[^\"\\\\])*)\"/)\n\t\t.token(\"STRING\", /'((?:\\\\.|[^'\\\\])*)'/)\n\n\t\t.token(\"COMMA\", \",\")\n\t\t.token(\"STAR\", \"*\")\n\t\t.token(\"(\", \"(\")\n\t\t.token(\":\", \":\")\n\t\t.token(\")\", \")\")\n\t\t.token('\"', '\"')\n\t\t.token(\"WS\", /\\s+/, true); // skip\n\nconst parseFilter = (filter: string): ExpressionSet => {\n\tconst lexer = getLexer(filter);\n\tconst parser = new Parser(lexer)\n\t\t.builder()\n\t\t.nud(\"IDENTIFIER\", 100, (t) => t.token.match)\n\t\t.led(\":\", 100, ({ left, bp }) => {\n\t\t\tconst parsed: any = parser.parse({ terminals: [bp - 1] });\n\t\t\tconst expressions: RangeExpression[] | FilterExpression[] | TypeSymbol[] =\n\t\t\t\t!Array.isArray(parsed) ? [parsed] : parsed;\n\n\t\t\t// Make sure we only have one type of expression (cannot mix)\n\t\t\tconst unique = new Set(expressions.map((expr) => expr.type));\n\t\t\tif (unique.size > 1) {\n\t\t\t\tthrow new Error(\"Invalid expression\");\n\t\t\t}\n\n\t\t\t// Convert plain symbols to a filter expression. For example\n\t\t\t// variants.attribute.foobar:4 where 4 is a Symbol should result\n\t\t\t// in a comparison\n\t\t\tif (expressions.some((expr) => expr.type === \"Symbol\")) {\n\t\t\t\treturn {\n\t\t\t\t\tsource: left as string,\n\t\t\t\t\ttype: \"FilterExpression\",\n\t\t\t\t\tchildren: expressions.map((e): FilterExpression => {\n\t\t\t\t\t\tif (e.type !== \"Symbol\") {\n\t\t\t\t\t\t\tthrow new Error(\"Invalid expression\");\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\ttype: \"FilterExpression\",\n\t\t\t\t\t\t\tmatch: (obj: any): boolean => obj === e.value,\n\t\t\t\t\t\t};\n\t\t\t\t\t}),\n\t\t\t\t};\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tsource: left,\n\t\t\t\ttype: expressions[0].type,\n\t\t\t\tchildren: expressions,\n\t\t\t};\n\t\t})\n\t\t.nud(\n\t\t\t\"STRING\",\n\t\t\t20,\n\t\t\t(t) =>\n\t\t\t\t({\n\t\t\t\t\ttype: \"Symbol\",\n\t\t\t\t\tkind: \"string\",\n\t\t\t\t\t// @ts-expect-error\n\t\t\t\t\tvalue: t.token.groups[1],\n\t\t\t\t}) as TypeSymbol,\n\t\t)\n\t\t.nud(\n\t\t\t\"INT\",\n\t\t\t5,\n\t\t\t(t) =>\n\t\t\t\t({\n\t\t\t\t\ttype: \"Symbol\",\n\t\t\t\t\tkind: \"int\",\n\t\t\t\t\tvalue: Number.parseInt(t.token.match, 10),\n\t\t\t\t}) as TypeSymbol,\n\t\t)\n\t\t.nud(\"STAR\", 5, (_) => ({\n\t\t\ttype: \"Symbol\",\n\t\t\tkind: \"any\",\n\t\t\tvalue: null,\n\t\t}))\n\t\t.nud(\n\t\t\t\"EXISTS\",\n\t\t\t10,\n\t\t\t({ bp }) =>\n\t\t\t\t({\n\t\t\t\t\ttype: \"FilterExpression\",\n\t\t\t\t\tmatch: (obj: any): boolean => obj !== undefined,\n\t\t\t\t}) as FilterExpression,\n\t\t)\n\t\t.nud(\n\t\t\t\"MISSING\",\n\t\t\t10,\n\t\t\t({ bp }) =>\n\t\t\t\t({\n\t\t\t\t\ttype: \"FilterExpression\",\n\t\t\t\t\tmatch: (obj: any): boolean => obj === undefined,\n\t\t\t\t}) as FilterExpression,\n\t\t)\n\t\t.led(\"COMMA\", 200, ({ left, token, bp }) => {\n\t\t\tconst expr: any = parser.parse({ terminals: [bp - 1] });\n\t\t\tif (Array.isArray(expr)) {\n\t\t\t\treturn [left, ...expr];\n\t\t\t}\n\t\t\treturn [left, expr];\n\t\t})\n\t\t.nud(\"(\", 100, (t) => {\n\t\t\tconst expr: any = parser.parse({ terminals: [\")\"] });\n\t\t\tlexer.expect(\")\");\n\t\t\treturn expr;\n\t\t})\n\t\t.bp(\")\", 0)\n\t\t.led(\"TO\", 20, ({ left, bp }) => {\n\t\t\tconst expr: any = parser.parse({ terminals: [bp - 1] });\n\t\t\treturn {\n\t\t\t\tstart: left.value,\n\t\t\t\tstop: expr.value,\n\t\t\t};\n\t\t})\n\t\t.nud(\"RANGE\", 20, ({ bp }) => {\n\t\t\tlet ranges: any = parser.parse();\n\n\t\t\t// If multiple ranges are defined we receive an array of ranges. So let's\n\t\t\t// make sure we always have an array\n\t\t\tif (!Array.isArray(ranges)) {\n\t\t\t\tranges = [ranges];\n\t\t\t}\n\n\t\t\t// Return a list of functions which matches the ranges. These functions\n\t\t\t// are processed as an OR clause\n\t\t\treturn ranges.map((range: any) => {\n\t\t\t\tlet func: (obj: any) => boolean;\n\n\t\t\t\tif (range.start !== null && range.stop !== null) {\n\t\t\t\t\tfunc = (obj: any): boolean => obj >= range.start && obj <= range.stop;\n\t\t\t\t} else if (range.start === null && range.stop !== null) {\n\t\t\t\t\tfunc = (obj: any): boolean => obj <= range.stop;\n\t\t\t\t} else if (range.start !== null && range.stop === null) {\n\t\t\t\t\tfunc = (obj: any): boolean => obj >= range.start;\n\t\t\t\t} else {\n\t\t\t\t\tfunc = (obj: any): boolean => true;\n\t\t\t\t}\n\n\t\t\t\treturn {\n\t\t\t\t\ttype: \"RangeExpression\",\n\t\t\t\t\tstart: range.start,\n\t\t\t\t\tstop: range.stop,\n\t\t\t\t\tmatch: func,\n\t\t\t\t} as RangeExpression;\n\t\t\t});\n\t\t})\n\t\t.build();\n\n\treturn parser.parse();\n};\n\nconst generateMatchFunc = (filter: string) => {\n\tconst result = parseFilter(filter);\n\tif (!result) {\n\t\t// const lines = filter.split('\\n')\n\t\t// const column = lines[lines.length - 1].length\n\t\tthrow new Error(`Syntax error while parsing '${filter}'.`);\n\t}\n\tif (result.type === \"TermExpression\") {\n\t\tthrow new Error(`Syntax error while parsing '${filter}'.`);\n\t}\n\n\treturn (obj: any) => {\n\t\tif (!result.children) return false;\n\t\treturn result.children.some((c) => c.match(obj));\n\t};\n};\n\nexport const generateFacetFunc = (filter: string): ExpressionSet => {\n\tif (!filter.includes(\":\")) {\n\t\treturn {\n\t\t\tsource: filter,\n\t\t\ttype: \"TermExpression\",\n\t\t};\n\t}\n\treturn parseFilter(filter);\n};\n\nconst filterProduct =\n\t(source: string, exprFunc: MatchFunc): ProductProjectionFilter =>\n\t(p: ProductProjection, markMatchingVariants: boolean): boolean => {\n\t\tconst value = nestedLookup(p, source);\n\t\treturn exprFunc(value);\n\t};\n\nconst filterVariants =\n\t(source: string, exprFunc: MatchFunc): ProductProjectionFilter =>\n\t(p: ProductProjection, markMatchingVariants: boolean): boolean => {\n\t\tconst [, ...paths] = source.split(\".\");\n\t\tconst path = paths.join(\".\");\n\n\t\tconst variants = getVariants(p) as Writable<ProductVariant>[];\n\t\tfor (const variant of variants) {\n\t\t\tconst value = resolveVariantValue(variant, path);\n\n\t\t\tif (exprFunc(value)) {\n\t\t\t\t// If markMatchingVariants parameter is true those ProductVariants that\n\t\t\t\t// match the search query have the additional field isMatchingVariant\n\t\t\t\t// set to true. For the other variants in the same product projection\n\t\t\t\t// this field is set to false.\n\t\t\t\tif (markMatchingVariants) {\n\t\t\t\t\tfor (const v of variants) {\n\t\t\t\t\t\tv.isMatchingVariant = false;\n\t\t\t\t\t}\n\t\t\t\t\tvariant.isMatchingVariant = true;\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\treturn false;\n\t};\n\nexport const resolveVariantValue = (obj: ProductVariant, path: string): any => {\n\tif (path === undefined) {\n\t\treturn obj;\n\t}\n\tif (path.startsWith(\"variants.\")) {\n\t\tpath = path.substring(path.indexOf(\".\") + 1);\n\t}\n\n\tif (path.startsWith(\"attributes.\")) {\n\t\tconst [, attrName, ...rest] = path.split(\".\");\n\t\tif (!obj.attributes) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tfor (const attr of obj.attributes) {\n\t\t\tif (attr.name === attrName) {\n\t\t\t\treturn nestedLookup(attr.value, rest.join(\".\"));\n\t\t\t}\n\t\t}\n\t}\n\n\tif (path === \"price.centAmount\") {\n\t\treturn obj.prices && obj.prices.length > 0\n\t\t\t? obj.prices[0].value.centAmount\n\t\t\t: undefined;\n\t}\n\n\treturn nestedLookup(obj, path);\n};\n\nexport const getVariants = (p: ProductProjection): ProductVariant[] => [\n\tp.masterVariant,\n\t...(p.variants ?? []),\n];\n","import type {\n\t_SearchQuery,\n\t_SearchQueryExpression,\n\t_SearchQueryExpressionValue,\n\tProductProjection,\n\tProductVariant,\n\tSearchAndExpression,\n\tSearchDateRangeExpression,\n\tSearchDateTimeRangeExpression,\n\tSearchExactExpression,\n\tSearchExistsExpression,\n\tSearchFilterExpression,\n\tSearchFullTextExpression,\n\tSearchFullTextPrefixExpression,\n\tSearchLongRangeExpression,\n\tSearchNotExpression,\n\tSearchNumberRangeExpression,\n\tSearchOrExpression,\n\tSearchPrefixExpression,\n\tSearchTimeRangeExpression,\n\tSearchWildCardExpression,\n} from \"@commercetools/platform-sdk\";\nimport { nestedLookup } from \"#src/helpers.ts\";\nimport type { Writable } from \"../types.ts\";\nimport { getVariants } from \"./projectionSearchFilter.ts\";\n\ntype ProductSearchFilterFunc = (\n\tp: Writable<ProductProjection>,\n\tmarkMatchingVariants: boolean,\n) => boolean;\n\n// @TODO: Implement field boosting:\n// https://docs.commercetools.com/merchant-center/advanced-product-search#boost-field\nexport const parseSearchQuery = (\n\tsearchQuery: _SearchQuery,\n): ProductSearchFilterFunc => {\n\tif (isSearchAndExpression(searchQuery)) {\n\t\treturn (obj, markMatchingVariant) =>\n\t\t\tsearchQuery.and.every((expr) => {\n\t\t\t\tconst filterFunc = parseSearchQuery(expr);\n\n\t\t\t\treturn filterFunc(obj, markMatchingVariant);\n\t\t\t});\n\t}\n\n\tif (isSearchOrExpression(searchQuery)) {\n\t\treturn (obj, markMatchingVariant) =>\n\t\t\tsearchQuery.or.some((expr) => {\n\t\t\t\tconst filterFunc = parseSearchQuery(expr);\n\n\t\t\t\treturn filterFunc(obj, markMatchingVariant);\n\t\t\t});\n\t}\n\n\tif (isSearchNotExpression(searchQuery)) {\n\t\treturn (obj, markMatchingVariant) =>\n\t\t\t!parseSearchQuery(searchQuery.not)(obj, markMatchingVariant);\n\t}\n\n\tif (isSearchFilterExpression(searchQuery)) {\n\t\t// Matching resources of a query are checked for their relevancy to the search.\n\t\t// The relevancy is expressed by an internal score.\n\t\t// All expressions except filter expressions contribute to that score.\n\t\t// All sub-expressions of a filter are implicitly connected with an and expression.\n\t\t// NOTE: for now just implementing it like a AND expression\n\t\treturn (obj, markMatchingVariant) =>\n\t\t\tsearchQuery.filter.every((expr) => {\n\t\t\t\tconst filterFunc = parseSearchQuery(expr);\n\n\t\t\t\treturn filterFunc(obj, markMatchingVariant);\n\t\t\t});\n\t}\n\n\tif (isSearchRangeExpression(searchQuery)) {\n\t\tconst generateRangeMatchFunc = (value: any) => {\n\t\t\tconst rangeFilters = [];\n\n\t\t\tif (searchQuery.range.gte) {\n\t\t\t\trangeFilters.push(value >= searchQuery.range.gte);\n\t\t\t}\n\n\t\t\tif (searchQuery.range.gt) {\n\t\t\t\trangeFilters.push(value > searchQuery.range.gt);\n\t\t\t}\n\n\t\t\tif (searchQuery.range.lte) {\n\t\t\t\trangeFilters.push(value <= searchQuery.range.lte);\n\t\t\t}\n\n\t\t\tif (searchQuery.range.lt) {\n\t\t\t\trangeFilters.push(value < searchQuery.range.lt);\n\t\t\t}\n\n\t\t\treturn rangeFilters.every((filter) => filter);\n\t\t};\n\n\t\treturn generateFieldMatchFunc(generateRangeMatchFunc, searchQuery.range);\n\t}\n\n\tif (isSearchExactExpression(searchQuery)) {\n\t\tif (Array.isArray(searchQuery.exact.values)) {\n\t\t\treturn generateFieldMatchFunc(\n\t\t\t\t(value: any) => (searchQuery.exact.values ?? []).includes(value),\n\t\t\t\tsearchQuery.exact,\n\t\t\t);\n\t\t}\n\n\t\treturn generateFieldMatchFunc(\n\t\t\t(value: any) => value === searchQuery.exact.value,\n\t\t\tsearchQuery.exact,\n\t\t);\n\t}\n\n\tif (isSearchExistsExpression(searchQuery)) {\n\t\treturn generateFieldMatchFunc((value: any) => !!value, searchQuery.exists);\n\t}\n\n\tif (isSearchFullTextExpression(searchQuery)) {\n\t\t// @TODO: Implement fulltext search, to fully support functionality offered by commercetools:\n\t\t// https://docs.commercetools.com/api/search-query-language#fulltext\n\t\treturn generateFieldMatchFunc(\n\t\t\t(value: any) => value.includes(searchQuery.fullText.value),\n\t\t\tsearchQuery.fullText,\n\t\t);\n\t}\n\n\tif (isSearchFullTextPrefixExpression(searchQuery)) {\n\t\t// @TODO: Implement fulltext search, to fully support functionality offered by commercetools:\n\t\t// https://docs.commercetools.com/api/search-query-language#fulltext\n\t\treturn generateFieldMatchFunc(\n\t\t\t(value: any) => value.startsWith(searchQuery.fullTextPrefix.value),\n\t\t\tsearchQuery.fullTextPrefix,\n\t\t);\n\t}\n\n\tif (isSearchPrefixExpression(searchQuery)) {\n\t\treturn generateFieldMatchFunc(\n\t\t\t(value: any) => value.startsWith(searchQuery.prefix.value),\n\t\t\tsearchQuery.prefix,\n\t\t);\n\t}\n\n\tif (isSearchWildCardExpression(searchQuery)) {\n\t\t// @TODO: Fully implement wildcard search, as specified:\n\t\t// https://docs.commercetools.com/api/search-query-language#fulltext\n\t\tconst generateWildcardMatchFunc = (value: any) => {\n\t\t\tconst wildCardValues = searchQuery.wildcard.value\n\t\t\t\t.split(\"*\")\n\t\t\t\t.filter((v: string) => !!v);\n\n\t\t\tif (searchQuery.wildcard.caseInsensitive) {\n\t\t\t\treturn wildCardValues.every((wildCardValue: string) =>\n\t\t\t\t\tvalue.toLowerCase().includes(wildCardValue.toLowerCase()),\n\t\t\t\t);\n\t\t\t}\n\n\t\t\treturn wildCardValues.every((wildCardValue: string) =>\n\t\t\t\tvalue.includes(wildCardValue),\n\t\t\t);\n\t\t};\n\n\t\treturn generateFieldMatchFunc(\n\t\t\tgenerateWildcardMatchFunc,\n\t\t\tsearchQuery.wildcard,\n\t\t);\n\t}\n\n\tthrow new Error(\"Unsupported search query expression\");\n};\n\nconst generateFieldMatchFunc = (\n\tmatchFunc: (value: any) => boolean,\n\tsearchQuery: _SearchQueryExpressionValue,\n) => {\n\tconst generateMatchFunc = (\n\t\tobj: ProductProjection,\n\t\tmarkMatchingVariants: boolean,\n\t) => {\n\t\tif (searchQuery.field.startsWith(\"variants.\")) {\n\t\t\tconst variantField = searchQuery.field.substring(\n\t\t\t\tsearchQuery.field.indexOf(\".\") + 1,\n\t\t\t);\n\n\t\t\tconst variants = getVariants(obj) as Writable<ProductVariant>[];\n\t\t\tfor (const variant of variants) {\n\t\t\t\tconst value = resolveFieldValue(variant, {\n\t\t\t\t\t...searchQuery,\n\t\t\t\t\tfield: variantField,\n\t\t\t\t});\n\n\t\t\t\tif (matchFunc(value)) {\n\t\t\t\t\tif (markMatchingVariants) {\n\t\t\t\t\t\tfor (const v of variants) {\n\t\t\t\t\t\t\tv.isMatchingVariant = false;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tvariant.isMatchingVariant = true;\n\t\t\t\t\t}\n\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn false;\n\t\t}\n\n\t\treturn matchFunc(resolveFieldValue(obj, searchQuery));\n\t};\n\n\treturn generateMatchFunc;\n};\n\nconst resolveFieldValue = (\n\tobj: any,\n\tsearchQuery: _SearchQueryExpressionValue,\n) => {\n\tif (searchQuery.field === undefined) {\n\t\tthrow new Error(\"Missing field path in query expression\");\n\t}\n\n\tlet fieldPath = searchQuery.field;\n\tconst language = \"language\" in searchQuery ? searchQuery.language : undefined;\n\n\tif (fieldPath.startsWith(\"variants.\")) {\n\t\tfieldPath = fieldPath.substring(fieldPath.indexOf(\".\") + 1);\n\t}\n\n\tif (fieldPath.startsWith(\"attributes.\")) {\n\t\tconst [, attrName, ...rest] = fieldPath.split(\".\");\n\t\tif (!obj.attributes) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tfor (const attr of obj.attributes) {\n\t\t\tif (attr.name === attrName) {\n\t\t\t\treturn nestedLookupByLanguage(attr.value, rest.join(\".\"), language);\n\t\t\t}\n\t\t}\n\t}\n\n\tif (fieldPath === \"prices.currentCentAmount\") {\n\t\treturn obj.prices && obj.prices.length > 0\n\t\t\t? obj.prices[0].value.centAmount\n\t\t\t: undefined;\n\t}\n\n\treturn nestedLookupByLanguage(obj, fieldPath, language);\n};\n\nconst nestedLookupByLanguage = (\n\tobj: any,\n\tpath: string,\n\tlanguage?: string,\n): any => {\n\tconst value = nestedLookup(obj, path);\n\n\tif (language && value && typeof value === \"object\") {\n\t\t// Due to Commercetools supporting \"en\", but also \"en-US\" as language, we need to find the best match\n\t\tconst matchingLanguageKey = Object.keys(value).find((key) =>\n\t\t\tkey.toLowerCase().startsWith(language.toLowerCase()),\n\t\t);\n\n\t\treturn matchingLanguageKey ? value[matchingLanguageKey] : undefined;\n\t}\n\n\treturn value;\n};\n\n// type guards\nconst isSearchAndExpression = (\n\texpr: _SearchQuery,\n): expr is SearchAndExpression =>\n\t(expr as SearchAndExpression).and !== undefined;\n\nconst isSearchOrExpression = (expr: _SearchQuery): expr is SearchOrExpression =>\n\t(expr as SearchOrExpression).or !== undefined;\n\ntype SearchRangeExpression =\n\t| SearchDateRangeExpression\n\t| SearchDateTimeRangeExpression\n\t| SearchLongRangeExpression\n\t| SearchNumberRangeExpression\n\t| SearchTimeRangeExpression;\n\n// Type guard for SearchNotExpression\nconst isSearchNotExpression = (\n\texpr: _SearchQueryExpression,\n): expr is SearchNotExpression =>\n\t(expr as SearchNotExpression).not !== undefined;\n\n// Type guard for SearchFilterExpression\nconst isSearchFilterExpression = (\n\texpr: _SearchQueryExpression,\n): expr is SearchFilterExpression =>\n\t(expr as SearchFilterExpression).filter !== undefined;\n\n// Type guard for SearchDateRangeExpression\nconst isSearchRangeExpression = (\n\texpr: _SearchQueryExpression,\n): expr is SearchRangeExpression =>\n\t(expr as SearchRangeExpression).range !== undefined;\n\n// Type guard for SearchExactExpression\nconst isSearchExactExpression = (\n\texpr: _SearchQueryExpression,\n): expr is SearchExactExpression =>\n\t(expr as SearchExactExpression).exact !== undefined;\n\n// Type guard for SearchExistsExpression\nconst isSearchExistsExpression = (\n\texpr: _SearchQueryExpression,\n): expr is SearchExistsExpression =>\n\t(expr as SearchExistsExpression).exists !== undefined;\n\n// Type guard for SearchFullTextExpression\nconst isSearchFullTextExpression = (\n\texpr: _SearchQueryExpression,\n): expr is SearchFullTextExpression =>\n\t(expr as SearchFullTextExpression).fullText !== undefined;\n\n// Type guard for SearchFullTextPrefixExpression\nconst isSearchFullTextPrefixExpression = (\n\texpr: _SearchQueryExpression,\n): expr is SearchFullTextPrefixExpression =>\n\t(expr as SearchFullTextPrefixExpression).fullTextPrefix !== undefined;\n\n// Type guard for SearchPrefixExpression\nconst isSearchPrefixExpression = (\n\texpr: _SearchQueryExpression,\n): expr is SearchPrefixExpression =>\n\t(expr as SearchPrefixExpression).prefix !== undefined;\n\n// Type guard for SearchWildCardExpression\nconst isSearchWildCardExpression = (\n\texpr: _SearchQueryExpression,\n): expr is SearchWildCardExpression =>\n\t(expr as SearchWildCardExpression).wildcard !== undefined;\n","import type {\n\t_SearchQuery,\n\t_SearchQueryExpression,\n\tSearchAndExpression,\n\tSearchAnyValue,\n\tSearchDateRangeExpression,\n\tSearchDateTimeRangeExpression,\n\tSearchExactExpression,\n\tSearchExistsExpression,\n\tSearchFilterExpression,\n\tSearchFullTextExpression,\n\tSearchFullTextPrefixExpression,\n\tSearchLongRangeExpression,\n\tSearchNotExpression,\n\tSearchNumberRangeExpression,\n\tSearchOrExpression,\n\tSearchPrefixExpression,\n\tSearchTimeRangeExpression,\n\tSearchWildCardExpression,\n} from \"@commercetools/platform-sdk\";\n\nexport const validateSearchQuery = (query: _SearchQuery): void => {\n\tif (isSearchAndExpression(query)) {\n\t\tfor (const expr of query.and) {\n\t\t\tvalidateSearchQuery(expr);\n\t\t}\n\t} else if (isSearchOrExpression(query)) {\n\t\tfor (const expr of query.or) {\n\t\t\tvalidateSearchQuery(expr);\n\t\t}\n\t} else if (isSearchNotExpression(query)) {\n\t\tvalidateSearchQuery(query.not);\n\t} else if (\n\t\tisSearchFilterExpression(query) ||\n\t\tisSearchRangeExpression(query) ||\n\t\tisSearchExactExpression(query) ||\n\t\tisSearchExistsExpression(query) ||\n\t\tisSearchFullTextExpression(query) ||\n\t\tisSearchFullTextPrefixExpression(query) ||\n\t\tisSearchPrefixExpression(query) ||\n\t\tisSearchWildCardExpression(query) ||\n\t\tisSearchAnyValue(query)\n\t) {\n\t\treturn;\n\t} else {\n\t\tthrow new Error(\"Unsupported search query expression\");\n\t}\n};\n\n// Type guards\nexport const isSearchAndExpression = (\n\texpr: _SearchQuery,\n): expr is SearchAndExpression =>\n\t(expr as SearchAndExpression).and !== undefined;\n\nexport const isSearchOrExpression = (\n\texpr: _SearchQuery,\n): expr is SearchOrExpression => (expr as SearchOrExpression).or !== undefined;\n\nexport type SearchRangeExpression =\n\t| SearchDateRangeExpression\n\t| SearchDateTimeRangeExpression\n\t| SearchLongRangeExpression\n\t| SearchNumberRangeExpression\n\t| SearchTimeRangeExpression;\n\n// Type guard for SearchNotExpression\nexport const isSearchNotExpression = (\n\texpr: _SearchQueryExpression,\n): expr is SearchNotExpression =>\n\t(expr as SearchNotExpression).not !== undefined;\n\n// Type guard for SearchFilterExpression\nexport const isSearchFilterExpression = (\n\texpr: _SearchQueryExpression,\n): expr is SearchFilterExpression =>\n\t(expr as SearchFilterExpression).filter !== undefined;\n\n// Type guard for SearchDateRangeExpression\nexport const isSearchRangeExpression = (\n\texpr: _SearchQueryExpression,\n): expr is SearchRangeExpression =>\n\t(expr as SearchRangeExpression).range !== undefined;\n\n// Type guard for SearchExactExpression\nexport const isSearchExactExpression = (\n\texpr: _SearchQueryExpression,\n): expr is SearchExactExpression =>\n\t(expr as SearchExactExpression).exact !== undefined;\n\n// Type guard for SearchExistsExpression\nexport const isSearchExistsExpression = (\n\texpr: _SearchQueryExpression,\n): expr is SearchExistsExpression =>\n\t(expr as SearchExistsExpression).exists !== undefined;\n\n// Type guard for SearchFullTextExpression\nexport const isSearchFullTextExpression = (\n\texpr: _SearchQueryExpression,\n): expr is SearchFullTextExpression =>\n\t(expr as SearchFullTextExpression).fullText !== undefined;\n\n// Type guard for SearchFullTextPrefixExpression\nexport const isSearchFullTextPrefixExpression = (\n\texpr: _SearchQueryExpression,\n): expr is SearchFullTextPrefixExpression =>\n\t(expr as SearchFullTextPrefixExpression).fullTextPrefix !== undefined;\n\n// Type guard for SearchPrefixExpression\nexport const isSearchPrefixExpression = (\n\texpr: _SearchQueryExpression,\n): expr is SearchPrefixExpression =>\n\t(expr as SearchPrefixExpression).prefix !== undefined;\n\n// Type guard for SearchWildCardExpression\nexport const isSearchWildCardExpression = (\n\texpr: _SearchQueryExpression,\n): expr is SearchWildCardExpression =>\n\t(expr as SearchWildCardExpression).wildcard !== undefined;\n\n// Type guard for SearchAnyValue\nexport const isSearchAnyValue = (\n\texpr: _SearchQueryExpression,\n): expr is SearchAnyValue => (expr as SearchAnyValue).value !== undefined;\n","import type {\n\tInvalidInputError,\n\tPrice,\n\tProductProjection,\n\tProductVariant,\n} from \"@commercetools/platform-sdk\";\nimport { CommercetoolsError } from \"./exceptions.ts\";\nimport type { Writable } from \"./types.ts\";\n\nexport type PriceSelector = {\n\tcurrency?: string;\n\tcountry?: string;\n\tcustomerGroup?: string;\n\tchannel?: string;\n};\n\n/**\n * Apply the price selector on all the variants. The price selector is applied\n * on all the prices per variant and the first match per variant is stored in\n * the scopedPrice attribute\n */\nexport const applyPriceSelector = (\n\tproducts: ProductProjection[],\n\tselector: PriceSelector,\n\tnoScopedPrice = false,\n) => {\n\tvalidatePriceSelector(selector);\n\n\tfor (const product of products) {\n\t\t// Get list of all variants (master + variants)\n\t\tconst variants: Writable<ProductVariant>[] = [\n\t\t\tproduct.masterVariant,\n\t\t\t...(product.variants ?? []),\n\t\t].filter((x) => x !== undefined);\n\n\t\tfor (const variant of variants) {\n\t\t\tconst scopedPrices =\n\t\t\t\tvariant.prices?.filter((p) => priceSelectorFilter(p, selector)) ?? [];\n\n\t\t\tif (scopedPrices.length > 0) {\n\t\t\t\tconst price = scopedPrices[0];\n\n\t\t\t\tvariant.price = scopedPrices[0];\n\t\t\t\tif (!noScopedPrice) {\n\t\t\t\t\tvariant.scopedPriceDiscounted = false;\n\t\t\t\t\tvariant.scopedPrice = {\n\t\t\t\t\t\t...price,\n\t\t\t\t\t\tcurrentValue: price.value,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n};\n\nconst validatePriceSelector = (selector: PriceSelector) => {\n\tif (\n\t\t(selector.country || selector.channel || selector.customerGroup) &&\n\t\t!selector.currency\n\t) {\n\t\tthrow new CommercetoolsError<InvalidInputError>(\n\t\t\t{\n\t\t\t\tcode: \"InvalidInput\",\n\t\t\t\tmessage:\n\t\t\t\t\t\"The price selecting parameters country, channel and customerGroup \" +\n\t\t\t\t\t\"cannot be used without the currency.\",\n\t\t\t},\n\t\t\t400,\n\t\t);\n\t}\n};\n\n/**\n * Return a boolean to indicate if the price matches the selector. Price\n * selection requires that if the selector or the price has a specific value\n * then it should match.\n */\nexport const priceSelectorFilter = (\n\tprice: Price,\n\tselector: PriceSelector,\n): boolean => {\n\tif (\n\t\t(selector.country || price.country) &&\n\t\tselector.country !== price.country\n\t) {\n\t\treturn false;\n\t}\n\n\tif (\n\t\t(selector.currency || price.value.currencyCode) &&\n\t\tselector.currency !== price.value.currencyCode\n\t) {\n\t\treturn false;\n\t}\n\n\tif (\n\t\t(selector.channel || price.channel?.id) &&\n\t\tselector.channel !== price.channel?.id\n\t) {\n\t\treturn false;\n\t}\n\n\tif (\n\t\t(selector.customerGroup || price.customerGroup?.id) &&\n\t\tselector.customerGroup !== price.customerGroup?.id\n\t) {\n\t\treturn false;\n\t}\n\n\treturn true;\n};\n","import type {\n\tInvalidInputError,\n\tProduct,\n\tProductPagedSearchResponse,\n\tProductProjection,\n\tProductSearchRequest,\n\tProductSearchResult,\n} from \"@commercetools/platform-sdk\";\nimport type { Config } from \"./config.ts\";\nimport { CommercetoolsError } from \"./exceptions.ts\";\nimport { parseSearchQuery } from \"./lib/productSearchFilter.ts\";\nimport { validateSearchQuery } from \"./lib/searchQueryTypeChecker.ts\";\nimport { applyPriceSelector } from \"./priceSelector.ts\";\nimport type { AbstractStorage } from \"./storage/index.ts\";\n\ninterface ProductSearchVariantAvailability {\n\tisOnStock: boolean;\n\tavailableQuantity: number;\n\tisOnStockForChannel: string | undefined;\n}\n\nexport class ProductSearch {\n\tprotected _storage: AbstractStorage;\n\n\tconstructor(config: Config) {\n\t\tthis._storage = config.storage;\n\t}\n\n\tsearch(\n\t\tprojectKey: string,\n\t\tparams: ProductSearchRequest,\n\t): ProductPagedSearchResponse {\n\t\tconst availabilityBySku = this._storage\n\t\t\t.all(projectKey, \"inventory-entry\")\n\t\t\t.reduce((acc, entry) => {\n\t\t\t\tconst existingEntry = acc.get(entry.sku);\n\n\t\t\t\tacc.set(entry.sku, {\n\t\t\t\t\tisOnStock: existingEntry?.isOnStock || entry.quantityOnStock > 0,\n\t\t\t\t\tavailableQuantity:\n\t\t\t\t\t\texistingEntry?.availableQuantity ?? 0 + entry.quantityOnStock,\n\t\t\t\t\t// NOTE: This doesn't handle inventory entries for multiple channels,\n\t\t\t\t\t// so it doesn't exactly replicate the behavior of the commercetools api.\n\t\t\t\t\tisOnStockForChannel:\n\t\t\t\t\t\texistingEntry?.isOnStockForChannel ?? entry.supplyChannel?.id,\n\t\t\t\t});\n\n\t\t\t\treturn acc;\n\t\t\t}, new Map<string, ProductSearchVariantAvailability>());\n\n\t\tlet productResources = this._storage\n\t\t\t.all(projectKey, \"product\")\n\t\t\t.map((r) =>\n\t\t\t\tthis.transformProduct(\n\t\t\t\t\tr,\n\t\t\t\t\tparams.productProjectionParameters?.staged ?? false,\n\t\t\t\t\tavailabilityBySku,\n\t\t\t\t),\n\t\t\t)\n\t\t\t.filter((p) => {\n\t\t\t\tif (!(params.productProjectionParameters?.staged ?? false)) {\n\t\t\t\t\treturn p.published;\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t});\n\n\t\tconst markMatchingVariant = params.markMatchingVariants ?? false;\n\n\t\t// Apply filters pre facetting\n\t\tif (params.query) {\n\t\t\ttry {\n\t\t\t\tvalidateSearchQuery(params.query);\n\n\t\t\t\tconst matchFunc = parseSearchQuery(params.query);\n\n\t\t\t\t// Filters can modify the output. So clone the resources first.\n\t\t\t\tproductResources = productResources.filter((resource) =>\n\t\t\t\t\tmatchFunc(resource, markMatchingVariant),\n\t\t\t\t);\n\t\t\t} catch (err) {\n\t\t\t\tthrow new CommercetoolsError<InvalidInputError>(\n\t\t\t\t\t{\n\t\t\t\t\t\tcode: \"InvalidInput\",\n\t\t\t\t\t\tmessage: (err as any).message,\n\t\t\t\t\t},\n\t\t\t\t\t400,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\t// Apply the priceSelector\n\t\tif (params.productProjectionParameters) {\n\t\t\tapplyPriceSelector(productResources, {\n\t\t\t\tcountry: params.productProjectionParameters.priceCountry,\n\t\t\t\tchannel: params.productProjectionParameters.priceChannel,\n\t\t\t\tcustomerGroup: params.productProjectionParameters.priceCustomerGroup,\n\t\t\t\tcurrency: params.productProjectionParameters.priceCurrency,\n\t\t\t});\n\t\t}\n\n\t\t// @TODO: Determine whether or not to spoof search, facet filtering, wildcard, boosting and/or sorting.\n\t\t// For now this is deliberately not supported.\n\n\t\tconst offset = params.offset || 0;\n\t\tconst limit = params.limit || 20;\n\t\tconst productProjectionsResult = productResources.slice(\n\t\t\toffset,\n\t\t\toffset + limit,\n\t\t);\n\n\t\t/**\n\t\t * Do not supply productProjection if productProjectionParameters are not given\n\t\t * https://docs.commercetools.com/api/projects/product-search#with-product-projection-parameters\n\t\t */\n\t\tconst productProjectionsParameterGiven =\n\t\t\t!!params?.productProjectionParameters;\n\n\t\t// Transform to ProductSearchResult\n\t\tconst results: ProductSearchResult[] = productProjectionsResult.map(\n\t\t\t(product) => ({\n\t\t\t\tproductProjection: productProjectionsParameterGiven\n\t\t\t\t\t? product\n\t\t\t\t\t: undefined,\n\t\t\t\tid: product.id,\n\t\t\t\t/**\n\t\t\t\t * @TODO: possibly add support for optional matchingVariants\n\t\t\t\t * \t\thttps://docs.commercetools.com/api/projects/product-search#productsearchmatchingvariants\n\t\t\t\t */\n\t\t\t}),\n\t\t);\n\n\t\treturn {\n\t\t\ttotal: productResources.length,\n\t\t\toffset: offset,\n\t\t\tlimit: limit,\n\t\t\tresults: results,\n\t\t\tfacets: [],\n\t\t};\n\t}\n\n\ttransformProduct(\n\t\tproduct: Product,\n\t\tstaged: boolean,\n\t\tavailabilityBySku: Map<string, ProductSearchVariantAvailability>,\n\t): ProductProjection {\n\t\tconst obj = !staged\n\t\t\t? product.masterData.current\n\t\t\t: product.masterData.staged;\n\n\t\tconst getVariantAvailability = (sku?: string) => {\n\t\t\tif (!sku) {\n\t\t\t\treturn {\n\t\t\t\t\tisOnStock: false,\n\t\t\t\t\tavailableQuantity: 0,\n\t\t\t\t\tisOnStockForChannel: undefined,\n\t\t\t\t};\n\t\t\t}\n\t\t\treturn (\n\t\t\t\tavailabilityBySku.get(sku) || {\n\t\t\t\t\tisOnStock: false,\n\t\t\t\t\tavailableQuantity: 0,\n\t\t\t\t\tisOnStockForChannel: undefined,\n\t\t\t\t}\n\t\t\t);\n\t\t};\n\n\t\treturn {\n\t\t\tid: product.id,\n\t\t\tcreatedAt: product.createdAt,\n\t\t\tlastModifiedAt: product.lastModifiedAt,\n\t\t\tversion: product.version,\n\t\t\tname: obj.name,\n\t\t\tkey: product.key,\n\t\t\tdescription: obj.description,\n\t\t\tmetaDescription: obj.metaDescription,\n\t\t\tslug: obj.slug,\n\t\t\tcategories: obj.categories,\n\t\t\tattributes: obj.attributes,\n\t\t\tmasterVariant: {\n\t\t\t\t...obj.masterVariant,\n\t\t\t\tavailability: getVariantAvailability(obj.masterVariant.sku),\n\t\t\t},\n\t\t\tvariants: obj.variants.map((variant) => ({\n\t\t\t\t...variant,\n\t\t\t\tavailability: getVariantAvailability(variant.sku),\n\t\t\t})),\n\t\t\tproductType: product.productType,\n\t\t\thasStagedChanges: product.masterData.hasStagedChanges,\n\t\t\tpublished: product.masterData.published,\n\t\t};\n\t}\n}\n","import { isDeepStrictEqual } from \"node:util\";\nimport type {\n\tAsset,\n\tAssetDraft,\n\tChannelReference,\n\tPrice,\n\tPriceDraft,\n\tProduct,\n\tProductData,\n\tProductVariant,\n\tProductVariantDraft,\n} from \"@commercetools/platform-sdk\";\nimport { v4 as uuidv4 } from \"uuid\";\nimport type { AbstractStorage } from \"#src/storage/index.ts\";\nimport type { Writable } from \"#src/types.ts\";\nimport type { RepositoryContext } from \"../abstract.ts\";\nimport {\n\tcreateCustomFields,\n\tcreateTypedMoney,\n\tgetReferenceFromResourceIdentifier,\n} from \"../helpers.ts\";\n\ninterface VariantResult {\n\tvariant: Writable<ProductVariant> | undefined;\n\tisMasterVariant: boolean;\n\tvariantIndex: number;\n}\n\nexport const getVariant = (\n\tproductData: ProductData,\n\tvariantId?: number,\n\tsku?: string,\n): VariantResult => {\n\tconst variants = [productData.masterVariant, ...productData.variants];\n\tconst foundVariant = variants.find((variant: ProductVariant) => {\n\t\tif (variantId) {\n\t\t\treturn variant.id === variantId;\n\t\t}\n\t\tif (sku) {\n\t\t\treturn variant.sku === sku;\n\t\t}\n\t\treturn false;\n\t});\n\n\tconst isMasterVariant = foundVariant === productData.masterVariant;\n\treturn {\n\t\tvariant: foundVariant,\n\t\tisMasterVariant,\n\t\tvariantIndex:\n\t\t\t!isMasterVariant && foundVariant\n\t\t\t\t? productData.variants.indexOf(foundVariant)\n\t\t\t\t: -1,\n\t};\n};\n\n// Check if the product still has staged data that is different from the\n// current data.\nexport const checkForStagedChanges = (product: Writable<Product>) => {\n\tif (!product.masterData.staged) {\n\t\tproduct.masterData.staged = product.masterData.current;\n\t}\n\n\tif (\n\t\tisDeepStrictEqual(product.masterData.current, product.masterData.staged)\n\t) {\n\t\tproduct.masterData.hasStagedChanges = false;\n\t} else {\n\t\tproduct.masterData.hasStagedChanges = true;\n\t}\n};\n\nexport const variantFromDraft = (\n\tcontext: RepositoryContext,\n\tstorage: AbstractStorage,\n\tvariantId: number,\n\tvariant: ProductVariantDraft,\n): ProductVariant => ({\n\tid: variantId,\n\tsku: variant?.sku,\n\tkey: variant?.key,\n\tattributes: variant?.attributes ?? [],\n\tprices: variant?.prices?.map((p) => priceFromDraft(context, storage, p)),\n\tassets: variant.assets?.map((a) => assetFromDraft(context, storage, a)) ?? [],\n\timages: variant.images ?? [],\n});\n\nexport const assetFromDraft = (\n\tcontext: RepositoryContext,\n\tstorage: AbstractStorage,\n\tdraft: AssetDraft,\n): Asset => {\n\tconst asset: Asset = {\n\t\t...draft,\n\t\tid: uuidv4(),\n\t\tcustom: createCustomFields(draft.custom, context.projectKey, storage),\n\t};\n\treturn asset;\n};\n\nexport const priceFromDraft = (\n\tcontext: RepositoryContext,\n\tstorage: AbstractStorage,\n\tdraft: PriceDraft,\n): Price => ({\n\tid: uuidv4(),\n\tkey: draft.key,\n\tcountry: draft.country,\n\tvalue: createTypedMoney(draft.value),\n\tchannel: draft.channel\n\t\t? getReferenceFromResourceIdentifier<ChannelReference>(\n\t\t\t\tdraft.channel,\n\t\t\t\tcontext.projectKey,\n\t\t\t\tstorage,\n\t\t\t)\n\t\t: undefined,\n});\n","import type {\n\tCategoryReference,\n\tInvalidJsonInputError,\n\tInvalidOperationError,\n\tPrice,\n\tProduct,\n\tProductAddExternalImageAction,\n\tProductAddPriceAction,\n\tProductAddToCategoryAction,\n\tProductAddVariantAction,\n\tProductChangeMasterVariantAction,\n\tProductChangeNameAction,\n\tProductChangePriceAction,\n\tProductChangeSlugAction,\n\tProductData,\n\tProductMoveImageToPositionAction,\n\tProductPublishAction,\n\tProductRemoveFromCategoryAction,\n\tProductRemoveImageAction,\n\tProductRemovePriceAction,\n\tProductRemoveVariantAction,\n\tProductSetAttributeAction,\n\tProductSetAttributeInAllVariantsAction,\n\tProductSetDescriptionAction,\n\tProductSetKeyAction,\n\tProductSetMetaDescriptionAction,\n\tProductSetMetaKeywordsAction,\n\tProductSetMetaTitleAction,\n\tProductSetProductPriceCustomFieldAction,\n\tProductSetProductPriceCustomTypeAction,\n\tProductSetTaxCategoryAction,\n\tProductTransitionStateAction,\n\tProductUpdateAction,\n\tProductVariantDraft,\n\tStateReference,\n\tTaxCategoryReference,\n} from \"@commercetools/platform-sdk\";\nimport { CommercetoolsError } from \"#src/exceptions.ts\";\nimport type { Writable } from \"#src/types.ts\";\nimport { AbstractUpdateHandler, type RepositoryContext } from \"../abstract.ts\";\nimport {\n\tcreateCustomFields,\n\tgetReferenceFromResourceIdentifier,\n} from \"../helpers.ts\";\nimport {\n\tcheckForStagedChanges,\n\tgetVariant,\n\tpriceFromDraft,\n\tvariantFromDraft,\n} from \"./helpers.ts\";\n\ntype ProductUpdateHandlerMethod<T> = (\n\tcontext: RepositoryContext,\n\tresource: Writable<Product>,\n\taction: T,\n) => void;\n\ntype ProductUpdateActions = Partial<{\n\t[P in ProductUpdateAction as P[\"action\"]]: ProductUpdateHandlerMethod<P>;\n}>;\n\nexport class ProductUpdateHandler\n\textends AbstractUpdateHandler\n\timplements ProductUpdateActions\n{\n\taddExternalImage(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Product>,\n\t\t{ variantId, sku, image, staged }: ProductAddExternalImageAction,\n\t) {\n\t\tconst addImg = (data: Writable<ProductData>) => {\n\t\t\tconst { variant, isMasterVariant, variantIndex } = getVariant(\n\t\t\t\tdata,\n\t\t\t\tvariantId,\n\t\t\t\tsku,\n\t\t\t);\n\t\t\tif (!variant) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Variant with id ${variantId} or sku ${sku} not found on product ${resource.id}`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tif (!variant.images) {\n\t\t\t\tvariant.images = [];\n\t\t\t} else {\n\t\t\t\tconst existingImage = variant.images.find((x) => x.url === image.url);\n\t\t\t\tif (existingImage) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`Cannot add image '${image.url}' because product '${resource.id}' already has that image.`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Add image\n\t\t\tvariant.images.push(image);\n\n\t\t\tif (isMasterVariant) {\n\t\t\t\tdata.masterVariant = variant;\n\t\t\t} else {\n\t\t\t\tdata.variants[variantIndex] = variant;\n\t\t\t}\n\t\t};\n\n\t\t// If true, only the staged Attribute is set. If false, both current and\n\t\t// staged Attribute is set. Default is true\n\t\tconst onlyStaged = staged !== undefined ? staged : true;\n\n\t\t// Write the attribute to the staged data\n\t\taddImg(resource.masterData.staged);\n\n\t\t// Also write to published data is isStaged = false\n\t\t// if isStaged is false we set the attribute on both the staged and\n\t\t// published data.\n\t\tif (!onlyStaged) {\n\t\t\taddImg(resource.masterData.current);\n\t\t}\n\t\tcheckForStagedChanges(resource);\n\n\t\treturn resource;\n\t}\n\n\taddPrice(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Product>,\n\t\t{ variantId, sku, price, staged }: ProductAddPriceAction,\n\t) {\n\t\tconst addVariantPrice = (\n\t\t\tdata: Writable<ProductData>,\n\t\t\tpriceToAdd: Price,\n\t\t) => {\n\t\t\tconst { variant, isMasterVariant, variantIndex } = getVariant(\n\t\t\t\tdata,\n\t\t\t\tvariantId,\n\t\t\t\tsku,\n\t\t\t);\n\t\t\tif (!variant) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Variant with id ${variantId} or sku ${sku} not found on product ${resource.id}`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tif (variant.prices === undefined) {\n\t\t\t\tvariant.prices = [priceToAdd];\n\t\t\t} else {\n\t\t\t\tvariant.prices.push(priceToAdd);\n\t\t\t}\n\n\t\t\tif (isMasterVariant) {\n\t\t\t\tdata.masterVariant = variant;\n\t\t\t} else {\n\t\t\t\tdata.variants[variantIndex] = variant;\n\t\t\t}\n\t\t};\n\n\t\t// Pre-creating the price object ensures consistency between staged and current versions\n\t\tconst priceToAdd = priceFromDraft(context, this._storage, price);\n\n\t\t// If true, only the staged Attribute is set. If false, both current and\n\t\t// staged Attribute is set. Default is true\n\t\tconst onlyStaged = staged !== undefined ? staged : true;\n\n\t\t// Write the attribute to the staged data\n\t\taddVariantPrice(resource.masterData.staged, priceToAdd);\n\n\t\t// Also write to published data is isStaged = false\n\t\t// if isStaged is false we set the attribute on both the staged and\n\t\t// published data.\n\t\tif (!onlyStaged) {\n\t\t\taddVariantPrice(resource.masterData.current, priceToAdd);\n\t\t}\n\t\tcheckForStagedChanges(resource);\n\n\t\treturn resource;\n\t}\n\n\taddToCategory(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Product>,\n\t\t{ category, staged, orderHint }: ProductAddToCategoryAction,\n\t) {\n\t\tconst addCategory = (data: Writable<ProductData>) => {\n\t\t\tif (category) {\n\t\t\t\tdata.categories.push(\n\t\t\t\t\tgetReferenceFromResourceIdentifier<CategoryReference>(\n\t\t\t\t\t\tcategory,\n\t\t\t\t\t\tcontext.projectKey,\n\t\t\t\t\t\tthis._storage,\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tthrow new CommercetoolsError<InvalidJsonInputError>(\n\t\t\t\t\t{\n\t\t\t\t\t\tcode: \"InvalidJsonInput\",\n\t\t\t\t\t\tmessage: \"Request body does not contain valid JSON.\",\n\t\t\t\t\t\tdetailedErrorMessage: \"actions -> category: Missing required value\",\n\t\t\t\t\t},\n\t\t\t\t\t400,\n\t\t\t\t);\n\t\t\t}\n\t\t};\n\n\t\tconst onlyStaged = staged !== undefined ? staged : true;\n\n\t\taddCategory(resource.masterData.staged);\n\n\t\tif (!onlyStaged) {\n\t\t\taddCategory(resource.masterData.current);\n\t\t}\n\t\tcheckForStagedChanges(resource);\n\n\t\treturn resource;\n\t}\n\n\taddVariant(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Product>,\n\t\t{\n\t\t\tsku,\n\t\t\tkey,\n\t\t\tprices,\n\t\t\timages,\n\t\t\tattributes,\n\t\t\tstaged,\n\t\t\tassets,\n\t\t}: ProductAddVariantAction,\n\t) {\n\t\tconst variantDraft: ProductVariantDraft = {\n\t\t\tsku: sku,\n\t\t\tkey: key,\n\t\t\tprices: prices,\n\t\t\timages: images,\n\t\t\tattributes: attributes,\n\t\t\tassets: assets,\n\t\t};\n\n\t\tconst dataStaged = resource.masterData.staged;\n\t\tconst allVariants = [\n\t\t\tdataStaged.masterVariant,\n\t\t\t...(dataStaged.variants ?? []),\n\t\t];\n\t\tconst maxId = allVariants.reduce(\n\t\t\t(max, element) => (element.id > max ? element.id : max),\n\t\t\t0,\n\t\t);\n\t\tconst variant = variantFromDraft(\n\t\t\tcontext,\n\t\t\tthis._storage,\n\t\t\tmaxId + 1,\n\t\t\tvariantDraft,\n\t\t);\n\t\tdataStaged.variants.push(variant);\n\n\t\tconst onlyStaged = staged !== undefined ? staged : true;\n\n\t\tif (!onlyStaged) {\n\t\t\tresource.masterData.current.variants.push(variant);\n\t\t}\n\t\tcheckForStagedChanges(resource);\n\n\t\treturn resource;\n\t}\n\n\tchangeMasterVariant(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Product>,\n\t\t{ variantId, sku, staged }: ProductChangeMasterVariantAction,\n\t) {\n\t\tconst setMaster = (data: Writable<ProductData>) => {\n\t\t\tconst { variant, isMasterVariant, variantIndex } = getVariant(\n\t\t\t\tdata,\n\t\t\t\tvariantId,\n\t\t\t\tsku,\n\t\t\t);\n\t\t\tif (!variant) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Variant with id ${variantId} or sku ${sku} not found on product ${resource.id}`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tif (!isMasterVariant) {\n\t\t\t\t// Save previous master variant\n\t\t\t\tconst masterVariantPrev = data.masterVariant;\n\t\t\t\tdata.masterVariant = variant;\n\t\t\t\t// Remove new master from variants\n\t\t\t\tdata.variants.splice(variantIndex, 1);\n\t\t\t\t// Add previous master to variants\n\t\t\t\tdata.variants.push(masterVariantPrev);\n\t\t\t}\n\t\t};\n\n\t\tconst onlyStaged = staged !== undefined ? staged : true;\n\n\t\tsetMaster(resource.masterData.staged);\n\n\t\tif (!onlyStaged) {\n\t\t\tsetMaster(resource.masterData.current);\n\t\t}\n\t\tcheckForStagedChanges(resource);\n\n\t\treturn resource;\n\t}\n\n\tchangeName(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Product>,\n\t\t{ name, staged }: ProductChangeNameAction,\n\t) {\n\t\tconst onlyStaged = staged !== undefined ? staged : true;\n\t\tresource.masterData.staged.name = name;\n\t\tif (!onlyStaged) {\n\t\t\tresource.masterData.current.name = name;\n\t\t}\n\t\tcheckForStagedChanges(resource);\n\t\treturn resource;\n\t}\n\n\tchangePrice(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Product>,\n\t\t{ priceId, price, staged }: ProductChangePriceAction,\n\t) {\n\t\tconst changeVariantPrice = (data: Writable<ProductData>) => {\n\t\t\tconst allVariants = [data.masterVariant, ...(data.variants ?? [])];\n\t\t\tconst priceVariant = allVariants.find((variant) =>\n\t\t\t\tvariant.prices?.some((x) => x.id === priceId),\n\t\t\t);\n\t\t\tif (!priceVariant) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Price with id ${priceId} not found on product ${resource.id}`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst { variant, isMasterVariant, variantIndex } = getVariant(\n\t\t\t\tdata,\n\t\t\t\tpriceVariant.id,\n\t\t\t\tpriceVariant.sku,\n\t\t\t);\n\t\t\tif (!variant) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Variant with id ${priceVariant.id} or sku ${priceVariant.sku} not found on product ${resource.id}`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tvariant.prices = variant.prices?.map((x) => {\n\t\t\t\tif (x.id === priceId) {\n\t\t\t\t\treturn { ...x, ...price } as Price;\n\t\t\t\t}\n\t\t\t\treturn x;\n\t\t\t});\n\n\t\t\tif (isMasterVariant) {\n\t\t\t\tdata.masterVariant = variant;\n\t\t\t} else {\n\t\t\t\tdata.variants[variantIndex] = variant;\n\t\t\t}\n\t\t};\n\n\t\t// If true, only the staged Attribute is set. If false, both current and\n\t\t// staged Attribute is set. Default is true\n\t\tconst onlyStaged = staged !== undefined ? staged : true;\n\n\t\t// Write the attribute to the staged data\n\t\tchangeVariantPrice(resource.masterData.staged);\n\n\t\t// Also write to published data is isStaged = false\n\t\t// if isStaged is false we set the attribute on both the staged and\n\t\t// published data.\n\t\tif (!onlyStaged) {\n\t\t\tchangeVariantPrice(resource.masterData.current);\n\t\t}\n\t\tcheckForStagedChanges(resource);\n\n\t\treturn resource;\n\t}\n\n\tchangeSlug(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Product>,\n\t\t{ slug, staged }: ProductChangeSlugAction,\n\t) {\n\t\tconst onlyStaged = staged !== undefined ? staged : true;\n\t\tresource.masterData.staged.slug = slug;\n\t\tif (!onlyStaged) {\n\t\t\tresource.masterData.current.slug = slug;\n\t\t}\n\t\tcheckForStagedChanges(resource);\n\t\treturn resource;\n\t}\n\n\tmoveImageToPosition(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Product>,\n\t\t{\n\t\t\tvariantId,\n\t\t\tsku,\n\t\t\timageUrl,\n\t\t\tposition,\n\t\t\tstaged,\n\t\t}: ProductMoveImageToPositionAction,\n\t) {\n\t\tconst moveImg = (data: Writable<ProductData>) => {\n\t\t\tconst { variant, isMasterVariant, variantIndex } = getVariant(\n\t\t\t\tdata,\n\t\t\t\tvariantId,\n\t\t\t\tsku,\n\t\t\t);\n\t\t\tif (!variant) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Variant with id ${variantId} or sku ${sku} not found on product ${resource.id}`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst variantImages = variant.images ?? [];\n\t\t\tconst existingImage = variantImages.find((x) => x.url === imageUrl);\n\t\t\tif (!existingImage) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Cannot move image '${imageUrl}' because product '${resource.id}' does not have that image.`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tif (position >= variantImages.length) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t\"Invalid position given. Position in images where the image should be moved. Must be between 0 and the total number of images minus 1.\",\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Remove image\n\t\t\tvariant.images = variantImages.filter((image) => image.url !== imageUrl);\n\n\t\t\t// Re-add image to the correct position\n\t\t\tvariant.images.splice(position, 0, existingImage);\n\n\t\t\tif (isMasterVariant) {\n\t\t\t\tdata.masterVariant = variant;\n\t\t\t} else {\n\t\t\t\tdata.variants[variantIndex] = variant;\n\t\t\t}\n\t\t};\n\n\t\t// If true, only the staged Attribute is set. If false, both current and\n\t\t// staged Attribute is set. Default is true\n\t\tconst onlyStaged = staged !== undefined ? staged : true;\n\n\t\t// Write the attribute to the staged data\n\t\tmoveImg(resource.masterData.staged);\n\n\t\t// Also write to published data is isStaged = false\n\t\t// if isStaged is false we set the attribute on both the staged and\n\t\t// published data.\n\t\tif (!onlyStaged) {\n\t\t\tmoveImg(resource.masterData.current);\n\t\t}\n\t\tcheckForStagedChanges(resource);\n\n\t\treturn resource;\n\t}\n\n\tpublish(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Product>,\n\t\t{ scope }: ProductPublishAction,\n\t) {\n\t\tresource.masterData.current = resource.masterData.staged;\n\t\tresource.masterData.published = true;\n\t\tcheckForStagedChanges(resource);\n\t}\n\n\tremoveFromCategory(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Product>,\n\t\t{ category, staged }: ProductRemoveFromCategoryAction,\n\t) {\n\t\tconst removeCategory = (data: Writable<ProductData>) => {\n\t\t\tif (category) {\n\t\t\t\tconst resolvedCategory =\n\t\t\t\t\tgetReferenceFromResourceIdentifier<CategoryReference>(\n\t\t\t\t\t\tcategory,\n\t\t\t\t\t\tcontext.projectKey,\n\t\t\t\t\t\tthis._storage,\n\t\t\t\t\t);\n\n\t\t\t\tconst foundCategory = data.categories.find(\n\t\t\t\t\t(productCategory: CategoryReference) => {\n\t\t\t\t\t\tif (productCategory.id === resolvedCategory.id) {\n\t\t\t\t\t\t\treturn productCategory;\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t},\n\t\t\t\t);\n\n\t\t\t\tif (!foundCategory) {\n\t\t\t\t\tthrow new CommercetoolsError<InvalidOperationError>(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcode: \"InvalidOperation\",\n\t\t\t\t\t\t\tmessage:\n\t\t\t\t\t\t\t\t`Cannot remove from category '${resolvedCategory.id}' because product ` +\n\t\t\t\t\t\t\t\t`'${resource.masterData.current.name}' is not in that category.`,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t400,\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tdata.categories = data.categories.filter(\n\t\t\t\t\t(productCategory: CategoryReference) => {\n\t\t\t\t\t\tif (productCategory.id === resolvedCategory.id) {\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tthrow new CommercetoolsError<InvalidJsonInputError>(\n\t\t\t\t\t{\n\t\t\t\t\t\tcode: \"InvalidJsonInput\",\n\t\t\t\t\t\tmessage: \"Request body does not contain valid JSON.\",\n\t\t\t\t\t\tdetailedErrorMessage: \"actions -> category: Missing required value\",\n\t\t\t\t\t},\n\t\t\t\t\t400,\n\t\t\t\t);\n\t\t\t}\n\t\t};\n\n\t\tconst onlyStaged = staged !== undefined ? staged : true;\n\t\tremoveCategory(resource.masterData.staged);\n\n\t\tif (!onlyStaged) {\n\t\t\tremoveCategory(resource.masterData.current);\n\t\t}\n\t\tcheckForStagedChanges(resource);\n\n\t\treturn resource;\n\t}\n\n\tremoveImage(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Product>,\n\t\t{ variantId, sku, imageUrl, staged }: ProductRemoveImageAction,\n\t) {\n\t\tconst removeImg = (data: Writable<ProductData>) => {\n\t\t\tconst { variant, isMasterVariant, variantIndex } = getVariant(\n\t\t\t\tdata,\n\t\t\t\tvariantId,\n\t\t\t\tsku,\n\t\t\t);\n\t\t\tif (!variant) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Variant with id ${variantId} or sku ${sku} not found on product ${resource.id}`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst variantImages = variant.images ?? [];\n\t\t\tconst existingImage = variantImages.find((x) => x.url === imageUrl);\n\t\t\tif (!existingImage) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Cannot remove image '${imageUrl}' because product '${resource.id}' does not have that image.`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Remove image\n\t\t\tvariant.images = variantImages.filter((image) => image.url !== imageUrl);\n\n\t\t\tif (isMasterVariant) {\n\t\t\t\tdata.masterVariant = variant;\n\t\t\t} else {\n\t\t\t\tdata.variants[variantIndex] = variant;\n\t\t\t}\n\t\t};\n\n\t\t// If true, only the staged Attribute is set. If false, both current and\n\t\t// staged Attribute is set. Default is true\n\t\tconst onlyStaged = staged !== undefined ? staged : true;\n\n\t\t// Write the attribute to the staged data\n\t\tremoveImg(resource.masterData.staged);\n\n\t\t// Also write to published data is isStaged = false\n\t\t// if isStaged is false we set the attribute on both the staged and\n\t\t// published data.\n\t\tif (!onlyStaged) {\n\t\t\tremoveImg(resource.masterData.current);\n\t\t}\n\t\tcheckForStagedChanges(resource);\n\n\t\treturn resource;\n\t}\n\n\tremovePrice(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Product>,\n\t\t{ priceId, staged }: ProductRemovePriceAction,\n\t) {\n\t\tconst removeVariantPrice = (data: Writable<ProductData>) => {\n\t\t\tconst allVariants = [data.masterVariant, ...(data.variants ?? [])];\n\t\t\tconst priceVariant = allVariants.find((variant) =>\n\t\t\t\tvariant.prices?.some((x) => x.id === priceId),\n\t\t\t);\n\t\t\tif (!priceVariant) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Price with id ${priceId} not found on product ${resource.id}`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst { variant, isMasterVariant, variantIndex } = getVariant(\n\t\t\t\tdata,\n\t\t\t\tpriceVariant.id,\n\t\t\t\tpriceVariant.sku,\n\t\t\t);\n\t\t\tif (!variant) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Variant with id ${priceVariant.id} or sku ${priceVariant.sku} not found on product ${resource.id}`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tvariant.prices = variant.prices?.filter((x) => x.id !== priceId);\n\n\t\t\tif (isMasterVariant) {\n\t\t\t\tdata.masterVariant = variant;\n\t\t\t} else {\n\t\t\t\tdata.variants[variantIndex] = variant;\n\t\t\t}\n\t\t};\n\n\t\t// If true, only the staged Attribute is set. If false, both current and\n\t\t// staged Attribute is set. Default is true\n\t\tconst onlyStaged = staged !== undefined ? staged : true;\n\n\t\t// Write the attribute to the staged data\n\t\tremoveVariantPrice(resource.masterData.staged);\n\n\t\t// Also write to published data is isStaged = false\n\t\t// if isStaged is false we set the attribute on both the staged and\n\t\t// published data.\n\t\tif (!onlyStaged) {\n\t\t\tremoveVariantPrice(resource.masterData.current);\n\t\t}\n\t\tcheckForStagedChanges(resource);\n\n\t\treturn resource;\n\t}\n\n\tremoveVariant(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Product>,\n\t\t{ id, sku, staged }: ProductRemoveVariantAction,\n\t) {\n\t\tconst removeVariant = (data: Writable<ProductData>) => {\n\t\t\tconst { variant, isMasterVariant, variantIndex } = getVariant(\n\t\t\t\tdata,\n\t\t\t\tid,\n\t\t\t\tsku,\n\t\t\t);\n\t\t\tif (!variant) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Variant with id ${id} or sku ${sku} not found on product ${resource.id}`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (isMasterVariant) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Can not remove the variant [ID:${id}] for [Product:${resource.id}] since it's the master variant`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tdata.variants.splice(variantIndex, 1);\n\t\t};\n\n\t\tconst onlyStaged = staged !== undefined ? staged : true;\n\n\t\tremoveVariant(resource.masterData.staged);\n\n\t\tif (!onlyStaged) {\n\t\t\tremoveVariant(resource.masterData.current);\n\t\t}\n\t\tcheckForStagedChanges(resource);\n\n\t\treturn resource;\n\t}\n\n\tsetAttribute(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Product>,\n\t\t{ variantId, sku, name, value, staged }: ProductSetAttributeAction,\n\t) {\n\t\tconst setAttr = (data: Writable<ProductData>) => {\n\t\t\tconst { variant, isMasterVariant, variantIndex } = getVariant(\n\t\t\t\tdata,\n\t\t\t\tvariantId,\n\t\t\t\tsku,\n\t\t\t);\n\t\t\tif (!variant) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Variant with id ${variantId} or sku ${sku} not found on product ${resource.id}`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tif (!variant.attributes) {\n\t\t\t\tvariant.attributes = [];\n\t\t\t}\n\n\t\t\tconst existingAttr = variant.attributes.find(\n\t\t\t\t(attr) => attr.name === name,\n\t\t\t);\n\t\t\tif (existingAttr) {\n\t\t\t\texistingAttr.value = value;\n\t\t\t} else {\n\t\t\t\tvariant.attributes.push({\n\t\t\t\t\tname,\n\t\t\t\t\tvalue,\n\t\t\t\t});\n\t\t\t}\n\t\t\tif (isMasterVariant) {\n\t\t\t\tdata.masterVariant = variant;\n\t\t\t} else {\n\t\t\t\tdata.variants[variantIndex] = variant;\n\t\t\t}\n\t\t};\n\n\t\t// If true, only the staged Attribute is set. If false, both current and\n\t\t// staged Attribute is set. Default is true\n\t\tconst onlyStaged = staged !== undefined ? staged : true;\n\n\t\t// Write the attribute to the staged data\n\t\tsetAttr(resource.masterData.staged);\n\n\t\t// Also write to published data is isStaged = false\n\t\t// if isStaged is false we set the attribute on both the staged and\n\t\t// published data.\n\t\tif (!onlyStaged) {\n\t\t\tsetAttr(resource.masterData.current);\n\t\t}\n\t\tcheckForStagedChanges(resource);\n\n\t\treturn resource;\n\t}\n\n\tsetAttributeInAllVariants(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Product>,\n\t\t{ name, value, staged }: ProductSetAttributeInAllVariantsAction,\n\t) {\n\t\tconst setAttrInAllVariants = (data: Writable<ProductData>) => {\n\t\t\tif (!data.masterVariant.attributes) {\n\t\t\t\tdata.masterVariant.attributes = [];\n\t\t\t}\n\n\t\t\tconst existingAttr = data.masterVariant.attributes?.find(\n\t\t\t\t(attr) => attr.name === name,\n\t\t\t);\n\n\t\t\tif (existingAttr) {\n\t\t\t\texistingAttr.value = value;\n\t\t\t} else {\n\t\t\t\tdata.masterVariant.attributes.push({\n\t\t\t\t\tname,\n\t\t\t\t\tvalue,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tdata.variants.forEach((variant) => {\n\t\t\t\tif (!variant.attributes) {\n\t\t\t\t\tvariant.attributes = [];\n\t\t\t\t}\n\n\t\t\t\tconst existingAttr = variant.attributes.find(\n\t\t\t\t\t(attr) => attr.name === name,\n\t\t\t\t);\n\t\t\t\tif (existingAttr) {\n\t\t\t\t\texistingAttr.value = value;\n\t\t\t\t} else {\n\t\t\t\t\tvariant.attributes.push({\n\t\t\t\t\t\tname,\n\t\t\t\t\t\tvalue,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t});\n\t\t};\n\n\t\t// If true, only the staged Attribute is set. If false, both current and\n\t\t// staged Attribute is set. Default is true\n\t\tconst onlyStaged = staged !== undefined ? staged : true;\n\n\t\t// Write the attribute to the staged data\n\t\tsetAttrInAllVariants(resource.masterData.staged);\n\n\t\t// Also write to published data is isStaged = false\n\t\t// if isStaged is false we set the attribute on both the staged and\n\t\t// published data.\n\t\tif (!onlyStaged) {\n\t\t\tsetAttrInAllVariants(resource.masterData.current);\n\t\t}\n\t\tcheckForStagedChanges(resource);\n\n\t\treturn resource;\n\t}\n\n\tsetDescription(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Product>,\n\t\t{ description, staged }: ProductSetDescriptionAction,\n\t) {\n\t\tconst onlyStaged = staged !== undefined ? staged : true;\n\n\t\tresource.masterData.staged.description = description;\n\t\tif (!onlyStaged) {\n\t\t\tresource.masterData.current.description = description;\n\t\t}\n\t\tcheckForStagedChanges(resource);\n\t\treturn resource;\n\t}\n\n\tsetKey(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Product>,\n\t\t{ key }: ProductSetKeyAction,\n\t) {\n\t\tresource.key = key;\n\t\treturn resource;\n\t}\n\n\tsetMetaDescription(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Product>,\n\t\t{ metaDescription, staged }: ProductSetMetaDescriptionAction,\n\t) {\n\t\tconst onlyStaged = staged !== undefined ? staged : true;\n\t\tresource.masterData.staged.metaDescription = metaDescription;\n\t\tif (!onlyStaged) {\n\t\t\tresource.masterData.current.metaDescription = metaDescription;\n\t\t}\n\t\tcheckForStagedChanges(resource);\n\t\treturn resource;\n\t}\n\n\tsetMetaKeywords(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Product>,\n\t\t{ metaKeywords, staged }: ProductSetMetaKeywordsAction,\n\t) {\n\t\tconst onlyStaged = staged !== undefined ? staged : true;\n\t\tresource.masterData.staged.metaKeywords = metaKeywords;\n\t\tif (!onlyStaged) {\n\t\t\tresource.masterData.current.metaKeywords = metaKeywords;\n\t\t}\n\t\tcheckForStagedChanges(resource);\n\t\treturn resource;\n\t}\n\n\tsetMetaTitle(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Product>,\n\t\t{ metaTitle, staged }: ProductSetMetaTitleAction,\n\t) {\n\t\tconst onlyStaged = staged !== undefined ? staged : true;\n\t\tresource.masterData.staged.metaTitle = metaTitle;\n\t\tif (!onlyStaged) {\n\t\t\tresource.masterData.current.metaTitle = metaTitle;\n\t\t}\n\t\tcheckForStagedChanges(resource);\n\t\treturn resource;\n\t}\n\n\tsetProductPriceCustomField(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Product>,\n\t\t{ name, value, staged, priceId }: ProductSetProductPriceCustomFieldAction,\n\t) {\n\t\tconst updatePriceCustomFields = (data: Writable<ProductData>) => {\n\t\t\tconst price = [data.masterVariant, ...(data.variants ?? [])]\n\t\t\t\t.flatMap((variant) => variant.prices ?? [])\n\t\t\t\t.find((price) => price.id === priceId);\n\n\t\t\tif (!price) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Price with id ${priceId} not found on product ${resource.id}`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (price.custom) {\n\t\t\t\tif (value === null) {\n\t\t\t\t\tdelete price.custom.fields[name];\n\t\t\t\t} else {\n\t\t\t\t\tprice.custom.fields[name] = value;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn data;\n\t\t};\n\n\t\tresource.masterData.staged = updatePriceCustomFields(\n\t\t\tresource.masterData.staged,\n\t\t);\n\n\t\tconst onlyStaged = staged !== undefined ? staged : true;\n\t\tif (!onlyStaged) {\n\t\t\tresource.masterData.current = updatePriceCustomFields(\n\t\t\t\tresource.masterData.current,\n\t\t\t);\n\t\t}\n\t\tcheckForStagedChanges(resource);\n\t\treturn resource;\n\t}\n\n\tsetProductPriceCustomType(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Product>,\n\t\t{ type, fields, staged, priceId }: ProductSetProductPriceCustomTypeAction,\n\t) {\n\t\tconst updatePriceCustomType = (data: Writable<ProductData>) => {\n\t\t\tconst price = [data.masterVariant, ...(data.variants ?? [])]\n\t\t\t\t.flatMap((variant) => variant.prices ?? [])\n\t\t\t\t.find((price) => price.id === priceId);\n\n\t\t\tif (price) {\n\t\t\t\tif (type) {\n\t\t\t\t\tprice.custom = createCustomFields(\n\t\t\t\t\t\t{ type, fields },\n\t\t\t\t\t\tcontext.projectKey,\n\t\t\t\t\t\tthis._storage,\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\tprice.custom = undefined;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Price with id ${priceId} not found on product ${resource.id}`,\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn data;\n\t\t};\n\n\t\tresource.masterData.staged = updatePriceCustomType(\n\t\t\tresource.masterData.staged,\n\t\t);\n\n\t\tconst onlyStaged = staged !== undefined ? staged : true;\n\t\tif (!onlyStaged) {\n\t\t\tresource.masterData.current = updatePriceCustomType(\n\t\t\t\tresource.masterData.current,\n\t\t\t);\n\t\t}\n\t\tcheckForStagedChanges(resource);\n\t\treturn resource;\n\t}\n\n\tsetTaxCategory(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Product>,\n\t\t{ taxCategory }: ProductSetTaxCategoryAction,\n\t) {\n\t\tlet taxCategoryReference: TaxCategoryReference | undefined;\n\t\tif (taxCategory) {\n\t\t\ttaxCategoryReference =\n\t\t\t\tgetReferenceFromResourceIdentifier<TaxCategoryReference>(\n\t\t\t\t\ttaxCategory,\n\t\t\t\t\tcontext.projectKey,\n\t\t\t\t\tthis._storage,\n\t\t\t\t);\n\t\t} else {\n\t\t\tthrow new CommercetoolsError<InvalidJsonInputError>(\n\t\t\t\t{\n\t\t\t\t\tcode: \"InvalidJsonInput\",\n\t\t\t\t\tmessage: \"Request body does not contain valid JSON.\",\n\t\t\t\t\tdetailedErrorMessage:\n\t\t\t\t\t\t\"actions -> taxCategory: Missing required value\",\n\t\t\t\t},\n\t\t\t\t400,\n\t\t\t);\n\t\t}\n\t\tresource.taxCategory = taxCategoryReference;\n\t\treturn resource;\n\t}\n\n\ttransitionState(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Product>,\n\t\t{ state, force }: ProductTransitionStateAction,\n\t) {\n\t\tlet productStateReference: StateReference | undefined;\n\t\tif (state) {\n\t\t\tproductStateReference =\n\t\t\t\tgetReferenceFromResourceIdentifier<StateReference>(\n\t\t\t\t\tstate,\n\t\t\t\t\tcontext.projectKey,\n\t\t\t\t\tthis._storage,\n\t\t\t\t);\n\t\t\tresource.state = productStateReference;\n\t\t} else {\n\t\t\tthrow new CommercetoolsError<InvalidJsonInputError>(\n\t\t\t\t{\n\t\t\t\t\tcode: \"InvalidJsonInput\",\n\t\t\t\t\tmessage: \"Request body does not contain valid JSON.\",\n\t\t\t\t\tdetailedErrorMessage: \"actions -> state: Missing required value\",\n\t\t\t\t},\n\t\t\t\t400,\n\t\t\t);\n\t\t}\n\n\t\treturn resource;\n\t}\n\n\tunpublish(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Product>,\n\t\t// { action }: ProductUnpublishAction\n\t) {\n\t\tresource.masterData.published = false;\n\t\tcheckForStagedChanges(resource);\n\t}\n\n\t// 'setPrices': () => {},\n\t// 'setDiscountedPrice': () => {},\n\t// 'setAttributeInAllVariants': () => {},\n\t// 'setCategoryOrderHint': () => {},\n\t// 'setSku': () => {},\n\t// 'setProductVariantKey': () => {},\n\t// 'setImageLabel': () => {},\n\t// 'addAsset': () => {},\n\t// 'removeAsset': () => {},\n\t// 'setAssetKey': () => {},\n\t// 'changeAssetOrder': () => {},\n\t// 'changeAssetName': () => {},\n\t// 'setAssetDescription': () => {},\n\t// 'setAssetTags': () => {},\n\t// 'setAssetSources': () => {},\n\t// 'setAssetCustomType': () => {},\n\t// 'setAssetCustomField': () => {},\n\t// 'setSearchKeywords': () => {},\n\t// 'revertStagedChanges': () => {},\n\t// 'revertStagedVariantChanges': () => {},\n}\n","import type {\n\tCategoryReference,\n\tInvalidJsonInputError,\n\tProduct,\n\tProductData,\n\tProductDraft,\n\tProductPagedSearchResponse,\n\tProductSearchRequest,\n\tProductTypeReference,\n\tStateReference,\n\tTaxCategoryReference,\n} from \"@commercetools/platform-sdk\";\nimport type { Config } from \"#src/config.ts\";\nimport { CommercetoolsError } from \"#src/exceptions.ts\";\nimport { getBaseResourceProperties } from \"#src/helpers.ts\";\nimport { ReviewStatisticsService } from \"#src/lib/review-statistics.ts\";\nimport { ProductSearch } from \"#src/product-search.ts\";\nimport type { GetParams, RepositoryContext } from \"../abstract.ts\";\nimport { AbstractResourceRepository } from \"../abstract.ts\";\nimport { getReferenceFromResourceIdentifier } from \"../helpers.ts\";\nimport { ProductUpdateHandler } from \"./actions.ts\";\nimport { variantFromDraft } from \"./helpers.ts\";\n\nexport class ProductRepository extends AbstractResourceRepository<\"product\"> {\n\tprotected _searchService: ProductSearch;\n\tprotected _reviewStatisticsService: ReviewStatisticsService;\n\n\tconstructor(config: Config) {\n\t\tsuper(\"product\", config);\n\t\tthis.actions = new ProductUpdateHandler(config.storage);\n\t\tthis._searchService = new ProductSearch(config);\n\t\tthis._reviewStatisticsService = new ReviewStatisticsService(config.storage);\n\t}\n\n\tcreate(context: RepositoryContext, draft: ProductDraft): Product {\n\t\tif (!draft.masterVariant) {\n\t\t\tthrow new Error(\"Missing master variant\");\n\t\t}\n\n\t\tlet productType: ProductTypeReference | undefined;\n\t\ttry {\n\t\t\tproductType = getReferenceFromResourceIdentifier<ProductTypeReference>(\n\t\t\t\tdraft.productType,\n\t\t\t\tcontext.projectKey,\n\t\t\t\tthis._storage,\n\t\t\t);\n\t\t} catch (err) {\n\t\t\tif (this.config.strict) {\n\t\t\t\tthrow err;\n\t\t\t}\n\n\t\t\t// For now accept missing product types (but warn)\n\t\t\tprocess.emitWarning(\n\t\t\t\t`Error resolving product-type '${draft.productType.id}'. This will be throw an error in later releases.`,\n\t\t\t);\n\t\t\tproductType = {\n\t\t\t\ttypeId: \"product-type\",\n\t\t\t\tid: draft.productType.id || \"\",\n\t\t\t};\n\t\t}\n\n\t\t// Resolve Product categories\n\t\tconst categoryReferences: CategoryReference[] = [];\n\t\tdraft.categories?.forEach((category) => {\n\t\t\tif (category) {\n\t\t\t\tcategoryReferences.push(\n\t\t\t\t\tgetReferenceFromResourceIdentifier<CategoryReference>(\n\t\t\t\t\t\tcategory,\n\t\t\t\t\t\tcontext.projectKey,\n\t\t\t\t\t\tthis._storage,\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tthrow new CommercetoolsError<InvalidJsonInputError>(\n\t\t\t\t\t{\n\t\t\t\t\t\tcode: \"InvalidJsonInput\",\n\t\t\t\t\t\tmessage: \"Request body does not contain valid JSON.\",\n\t\t\t\t\t\tdetailedErrorMessage: \"categories: JSON object expected.\",\n\t\t\t\t\t},\n\t\t\t\t\t400,\n\t\t\t\t);\n\t\t\t}\n\t\t});\n\n\t\t// Resolve Tax category\n\t\tlet taxCategoryReference: TaxCategoryReference | undefined;\n\t\tif (draft.taxCategory) {\n\t\t\ttaxCategoryReference =\n\t\t\t\tgetReferenceFromResourceIdentifier<TaxCategoryReference>(\n\t\t\t\t\tdraft.taxCategory,\n\t\t\t\t\tcontext.projectKey,\n\t\t\t\t\tthis._storage,\n\t\t\t\t);\n\t\t}\n\n\t\t// Resolve Product State\n\t\tlet productStateReference: StateReference | undefined;\n\t\tif (draft.state) {\n\t\t\tproductStateReference =\n\t\t\t\tgetReferenceFromResourceIdentifier<StateReference>(\n\t\t\t\t\tdraft.state,\n\t\t\t\t\tcontext.projectKey,\n\t\t\t\t\tthis._storage,\n\t\t\t\t);\n\t\t}\n\n\t\tconst productData: ProductData = {\n\t\t\tname: draft.name,\n\t\t\tslug: draft.slug,\n\t\t\tdescription: draft.description,\n\t\t\tattributes: draft.attributes ?? [],\n\t\t\tcategories: categoryReferences,\n\t\t\tmasterVariant: variantFromDraft(\n\t\t\t\tcontext,\n\t\t\t\tthis._storage,\n\t\t\t\t1,\n\t\t\t\tdraft.masterVariant,\n\t\t\t),\n\t\t\tvariants:\n\t\t\t\tdraft.variants?.map((variant, index) =>\n\t\t\t\t\tvariantFromDraft(context, this._storage, index + 2, variant),\n\t\t\t\t) ?? [],\n\t\t\tmetaTitle: draft.metaTitle,\n\t\t\tmetaDescription: draft.metaDescription,\n\t\t\tmetaKeywords: draft.metaKeywords,\n\t\t\tsearchKeywords: draft.searchKeywords ?? {},\n\t\t};\n\n\t\tconst resource: Product = {\n\t\t\t...getBaseResourceProperties(),\n\t\t\tkey: draft.key,\n\t\t\tproductType: productType,\n\t\t\ttaxCategory: taxCategoryReference,\n\t\t\tstate: productStateReference,\n\t\t\tmasterData: {\n\t\t\t\tcurrent: productData,\n\t\t\t\tstaged: productData,\n\t\t\t\thasStagedChanges: false,\n\t\t\t\tpublished: draft.publish ?? false,\n\t\t\t},\n\t\t};\n\n\t\treturn this.saveNew(context, resource);\n\t}\n\n\tpostProcessResource(\n\t\tcontext: RepositoryContext,\n\t\tresource: Product,\n\t\tparams?: GetParams,\n\t): Product {\n\t\t// Add review statistics to the product\n\t\tconst reviewStatistics =\n\t\t\tthis._reviewStatisticsService.calculateProductReviewStatistics(\n\t\t\t\tcontext.projectKey,\n\t\t\t\tresource.id,\n\t\t\t);\n\n\t\treturn {\n\t\t\t...resource,\n\t\t\treviewRatingStatistics: reviewStatistics,\n\t\t};\n\t}\n\n\tsearch(\n\t\tcontext: RepositoryContext,\n\t\tsearchRequest: ProductSearchRequest,\n\t): ProductPagedSearchResponse {\n\t\treturn this._searchService.search(context.projectKey, searchRequest);\n\t}\n}\n","import type {\n\tProductDiscount,\n\tProductDiscountChangeIsActiveAction,\n\tProductDiscountChangeNameAction,\n\tProductDiscountChangePredicateAction,\n\tProductDiscountChangeSortOrderAction,\n\tProductDiscountChangeValueAction,\n\tProductDiscountDraft,\n\tProductDiscountSetDescriptionAction,\n\tProductDiscountSetKeyAction,\n\tProductDiscountSetValidFromAction,\n\tProductDiscountSetValidFromAndUntilAction,\n\tProductDiscountSetValidUntilAction,\n\tProductDiscountUpdateAction,\n\tProductDiscountValue,\n\tProductDiscountValueAbsolute,\n\tProductDiscountValueDraft,\n\tProductDiscountValueExternal,\n\tProductDiscountValueRelative,\n} from \"@commercetools/platform-sdk\";\nimport type { Config } from \"#src/config.ts\";\nimport { getBaseResourceProperties } from \"../helpers.ts\";\nimport type { Writable } from \"../types.ts\";\nimport type { RepositoryContext, UpdateHandlerInterface } from \"./abstract.ts\";\nimport {\n\tAbstractResourceRepository,\n\tAbstractUpdateHandler,\n} from \"./abstract.ts\";\nimport { createTypedMoney } from \"./helpers.ts\";\n\nexport class ProductDiscountRepository extends AbstractResourceRepository<\"product-discount\"> {\n\tconstructor(config: Config) {\n\t\tsuper(\"product-discount\", config);\n\t\tthis.actions = new ProductDiscountUpdateHandler(this._storage);\n\t}\n\n\tcreate(\n\t\tcontext: RepositoryContext,\n\t\tdraft: ProductDiscountDraft,\n\t): ProductDiscount {\n\t\tconst resource: ProductDiscount = {\n\t\t\t...getBaseResourceProperties(),\n\t\t\tkey: draft.key,\n\t\t\tname: draft.name,\n\t\t\tdescription: draft.description,\n\t\t\tvalue: transformValueDraft(draft.value),\n\t\t\tpredicate: draft.predicate,\n\t\t\tsortOrder: draft.sortOrder,\n\t\t\tisActive: draft.isActive || false,\n\t\t\tvalidFrom: draft.validFrom,\n\t\t\tvalidUntil: draft.validUntil,\n\t\t\treferences: [],\n\t\t};\n\t\treturn this.saveNew(context, resource);\n\t}\n}\n\nconst transformValueDraft = (\n\tvalue: ProductDiscountValueDraft,\n): ProductDiscountValue => {\n\tswitch (value.type) {\n\t\tcase \"absolute\": {\n\t\t\treturn {\n\t\t\t\ttype: \"absolute\",\n\t\t\t\tmoney: value.money.map(createTypedMoney),\n\t\t\t} as ProductDiscountValueAbsolute;\n\t\t}\n\t\tcase \"external\": {\n\t\t\treturn {\n\t\t\t\ttype: \"external\",\n\t\t\t} as ProductDiscountValueExternal;\n\t\t}\n\t\tcase \"relative\": {\n\t\t\treturn {\n\t\t\t\t...value,\n\t\t\t} as ProductDiscountValueRelative;\n\t\t}\n\t}\n};\n\nexport class ProductDiscountUpdateHandler\n\textends AbstractUpdateHandler\n\timplements\n\t\tUpdateHandlerInterface<ProductDiscount, ProductDiscountUpdateAction>\n{\n\tchangeIsActive(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<ProductDiscount>,\n\t\t{ isActive }: ProductDiscountChangeIsActiveAction,\n\t) {\n\t\tresource.isActive = isActive;\n\t}\n\n\tchangeName(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<ProductDiscount>,\n\t\t{ name }: ProductDiscountChangeNameAction,\n\t) {\n\t\tresource.name = name;\n\t}\n\n\tchangePredicate(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<ProductDiscount>,\n\t\t{ predicate }: ProductDiscountChangePredicateAction,\n\t) {\n\t\tresource.predicate = predicate;\n\t}\n\n\tchangeSortOrder(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<ProductDiscount>,\n\t\t{ sortOrder }: ProductDiscountChangeSortOrderAction,\n\t) {\n\t\tresource.sortOrder = sortOrder;\n\t}\n\n\tchangeValue(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<ProductDiscount>,\n\t\t{ value }: ProductDiscountChangeValueAction,\n\t) {\n\t\tresource.value = transformValueDraft(value);\n\t}\n\n\tsetDescription(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<ProductDiscount>,\n\t\t{ description }: ProductDiscountSetDescriptionAction,\n\t) {\n\t\tif (description && Object.keys(description).length > 0) {\n\t\t\tresource.description = description;\n\t\t} else {\n\t\t\tresource.description = undefined;\n\t\t}\n\t}\n\n\tsetKey(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<ProductDiscount>,\n\t\t{ key }: ProductDiscountSetKeyAction,\n\t) {\n\t\tresource.key = key;\n\t}\n\n\tsetValidFrom(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<ProductDiscount>,\n\t\t{ validFrom }: ProductDiscountSetValidFromAction,\n\t) {\n\t\tresource.validFrom = validFrom;\n\t}\n\n\tsetValidFromAndUntil(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<ProductDiscount>,\n\t\t{ validFrom, validUntil }: ProductDiscountSetValidFromAndUntilAction,\n\t) {\n\t\tresource.validFrom = validFrom;\n\t\tresource.validUntil = validUntil;\n\t}\n\n\tsetValidUntil(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<ProductDiscount>,\n\t\t{ validUntil }: ProductDiscountSetValidUntilAction,\n\t) {\n\t\tresource.validUntil = validUntil;\n\t}\n}\n","export type Location = {\n\tlatitude: number;\n\tlongitude: number;\n};\n\n/**\n * Returns the distance between src and dst as meters\n */\nexport const haversineDistance = (src: Location, dst: Location) => {\n\tconst RADIUS_OF_EARTH_IN_KM = 6371;\n\tconst toRadian = (deg: number) => deg * (Math.PI / 180);\n\n\tconst dLat = toRadian(dst.latitude - src.latitude);\n\tconst dLon = toRadian(dst.longitude - src.longitude);\n\n\tconst a =\n\t\tMath.sin(dLat / 2) * Math.sin(dLat / 2) +\n\t\tMath.cos(toRadian(src.latitude)) *\n\t\t\tMath.cos(toRadian(dst.latitude)) *\n\t\t\tMath.sin(dLon / 2) *\n\t\t\tMath.sin(dLon / 2);\n\tconst c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));\n\treturn RADIUS_OF_EARTH_IN_KM * c * 1000;\n};\n","/**\n * This module implements the commercetools query predicate filter expression.\n * Support should be 100% complete.\n *\n * See https://docs.commercetools.com/api/predicates/query\n */\nimport { haversineDistance } from \"./haversine.ts\";\nimport { type ITokenPosition, Lexer, Parser } from \"./parser.ts\";\n\nexport class PredicateError {\n\tmessage: string;\n\n\tconstructor(message: string) {\n\t\tthis.message = message;\n\t}\n}\n\ntype MatchFunc = (target: any, variables: VariableMap) => boolean;\ntype VariableMap = {\n\t[key: string]: any;\n};\n\nexport const matchesPredicate = (\n\tpredicate: string | string[] | undefined,\n\ttarget: any,\n\tvariables?: VariableMap,\n): boolean => {\n\tif (!predicate) {\n\t\treturn true;\n\t}\n\n\tif (Array.isArray(predicate)) {\n\t\treturn predicate.every((item) => {\n\t\t\tconst func = generateMatchFunc(item);\n\t\t\treturn func(target, variables ?? {});\n\t\t});\n\t}\n\tconst func = generateMatchFunc(predicate);\n\treturn func(target, variables ?? {});\n};\n\nexport const parseQueryExpression = (\n\tpredicate: string | string[],\n): MatchFunc => {\n\tif (Array.isArray(predicate)) {\n\t\tconst callbacks = predicate.map((item) => generateMatchFunc(item));\n\t\treturn (target: any, variables: VariableMap) =>\n\t\t\tcallbacks.every((callback) => callback(target, variables));\n\t}\n\treturn generateMatchFunc(predicate);\n};\n\ntype TypeSymbol = {\n\ttype: \"var\" | \"boolean\" | \"string\" | \"float\" | \"int\" | \"identifier\";\n\tvalue: any;\n\tpos?: ITokenPosition;\n};\n\nconst validateSymbol = (val: TypeSymbol) => {\n\tif (!val.type) {\n\t\tthrow new PredicateError(\"Internal error\");\n\t}\n\n\tif (val.type === \"identifier\") {\n\t\tconst char = val.value.charAt(0);\n\t\tconst line = val.pos?.start.line;\n\t\tconst column = val.pos?.start.column;\n\n\t\tthrow new PredicateError(\n\t\t\t`Invalid input '${char}', expected input parameter or primitive value (line ${line}, column ${column})`,\n\t\t);\n\t}\n};\n\nconst resolveSymbol = (val: TypeSymbol, vars: VariableMap): any => {\n\tif (val.type === \"var\") {\n\t\tif (!(val.value in (vars ?? {}))) {\n\t\t\tthrow new PredicateError(`Missing parameter value for ${val.value}`);\n\t\t}\n\t\treturn vars[val.value];\n\t}\n\n\treturn val.value;\n};\n\nconst resolveValue = (obj: any, val: TypeSymbol): any => {\n\tif (val.type !== \"identifier\") {\n\t\tthrow new PredicateError(\"Internal error\");\n\t}\n\n\t// variants() includes both masterVariant and variants for predicates\n\tif (\n\t\tval.value === \"variants\" &&\n\t\tobj.masterVariant &&\n\t\tobj.variants !== undefined\n\t) {\n\t\treturn [obj.masterVariant, ...(obj.variants ?? [])];\n\t}\n\n\tif (!(val.value in obj)) {\n\t\tif (Array.isArray(obj)) {\n\t\t\treturn Object.values(obj)\n\t\t\t\t.filter((v) => val.value in v)\n\t\t\t\t.map((v) => v[val.value]);\n\t\t}\n\n\t\t// TODO: We don't really validate the shape of the object here. To actually\n\t\t// match commercetools behaviour we should throw an error if the requested\n\t\t// field doesn't exist (unless it's a map)\n\t\t// throw new PredicateError(`The field '${val.value}' does not exist.`)\n\t\treturn undefined;\n\t}\n\n\treturn obj[val.value];\n};\n\nconst getLexer = (value: string) =>\n\tnew Lexer(value)\n\n\t\t.token(\"AND\", /and(?![-_a-z0-9]+)/i)\n\t\t.token(\"OR\", /or(?![-_a-z0-9]+)/i)\n\t\t.token(\"NOT\", /not(?![-_a-z0-9]+)/i)\n\n\t\t.token(\"WITHIN\", /within(?![-_a-z0-9]+)/i)\n\t\t.token(\"IN\", /in(?![-_a-z0-9]+)/i)\n\t\t.token(\"MATCHES_IGNORE_CASE\", /matches\\s+ignore\\s+case(?![-_a-z0-9]+)/i)\n\t\t.token(\"CONTAINS\", /contains(?![-_a-z0-9]+)/i)\n\t\t.token(\"ALL\", /all(?![-_a-z0-9]+)/i)\n\t\t.token(\"ANY\", /any(?![-_a-z0-9]+)/i)\n\t\t.token(\"EMPTY\", /empty(?![-_a-z0-9]+)/i)\n\t\t.token(\"IS\", /is(?![-_a-z0-9]+)/i)\n\t\t.token(\"DEFINED\", /defined(?![-_a-z0-9]+)/i)\n\n\t\t// Special case for UUID identifiers,\n\t\t// since they otherwise would get matched as INT, when starting with a digit\n\t\t.token(\n\t\t\t\"IDENTIFIER\",\n\t\t\t/[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}/,\n\t\t)\n\t\t.token(\"FLOAT\", /\\d+\\.\\d+/)\n\t\t.token(\"INT\", /\\d+/)\n\t\t.token(\"VARIABLE\", /:([-_A-Za-z0-9]+)/)\n\t\t.token(\"BOOLEAN\", /(true|false)/)\n\t\t.token(\"IDENTIFIER\", /[-_A-Za-z0-9]+/)\n\t\t.token(\"STRING\", /\"((?:\\\\.|[^\"\\\\])*)\"/)\n\t\t.token(\"STRING\", /'((?:\\\\.|[^'\\\\])*)'/)\n\n\t\t.token(\"COMMA\", \",\")\n\t\t.token(\"(\", \"(\")\n\t\t.token(\")\", \")\")\n\t\t.token(\">=\", \">=\")\n\t\t.token(\"<=\", \"<=\")\n\t\t.token(\">\", \">\")\n\t\t.token(\"<\", \"<\")\n\t\t.token(\"!=\", \"!=\")\n\t\t.token(\"=\", \"=\")\n\t\t.token('\"', '\"')\n\t\t.token(\"WS\", /\\s+/, true); // skip\n\n/**\n * This function converts a query expression in to a callable which returns a\n * boolean to indicate if the given object matches or not.\n *\n * This currently parses the predicate each time it is called, but it should be\n * straight-forward to add a query cache (lru-cache)\n */\nconst generateMatchFunc = (predicate: string): MatchFunc => {\n\tconst lexer = getLexer(predicate);\n\tconst parser = new Parser(lexer)\n\t\t.builder()\n\t\t.nud(\n\t\t\t\"IDENTIFIER\",\n\t\t\t100,\n\t\t\t(t) =>\n\t\t\t\t({\n\t\t\t\t\ttype: \"identifier\",\n\t\t\t\t\tvalue: t.token.match,\n\t\t\t\t\tpos: t.token.strpos(),\n\t\t\t\t}) as TypeSymbol,\n\t\t)\n\t\t.nud(\n\t\t\t\"BOOLEAN\",\n\t\t\t1,\n\t\t\t(t) =>\n\t\t\t\t({\n\t\t\t\t\ttype: \"boolean\",\n\t\t\t\t\tvalue: t.token.match === \"true\",\n\t\t\t\t\tpos: t.token.strpos(),\n\t\t\t\t}) as TypeSymbol,\n\t\t)\n\t\t.nud(\n\t\t\t\"VARIABLE\",\n\t\t\t100,\n\t\t\t(t) =>\n\t\t\t\t({\n\t\t\t\t\ttype: \"var\",\n\t\t\t\t\t// @ts-expect-error\n\t\t\t\t\tvalue: t.token.groups[1],\n\t\t\t\t\tpos: t.token.strpos(),\n\t\t\t\t}) as TypeSymbol,\n\t\t)\n\t\t.nud(\n\t\t\t\"STRING\",\n\t\t\t100,\n\t\t\t(t) =>\n\t\t\t\t({\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t// @ts-expect-error\n\t\t\t\t\tvalue: t.token.groups[1],\n\t\t\t\t\tpos: t.token.strpos(),\n\t\t\t\t}) as TypeSymbol,\n\t\t)\n\t\t.nud(\n\t\t\t\"INT\",\n\t\t\t1,\n\t\t\t(t) =>\n\t\t\t\t({\n\t\t\t\t\ttype: \"int\",\n\t\t\t\t\tvalue: Number.parseInt(t.token.match, 10),\n\t\t\t\t\tpos: t.token.strpos(),\n\t\t\t\t}) as TypeSymbol,\n\t\t)\n\t\t.nud(\n\t\t\t\"FLOAT\",\n\t\t\t1,\n\t\t\t(t) =>\n\t\t\t\t({\n\t\t\t\t\ttype: \"float\",\n\t\t\t\t\tvalue: Number.parseFloat(t.token.match),\n\t\t\t\t\tpos: t.token.strpos(),\n\t\t\t\t}) as TypeSymbol,\n\t\t)\n\t\t.nud(\"NOT\", 100, ({ bp }) => {\n\t\t\tconst expr = parser.parse({ terminals: [bp - 1] });\n\t\t\treturn (obj: any) => !expr(obj);\n\t\t})\n\t\t.nud(\"EMPTY\", 10, ({ bp }) => \"empty\")\n\t\t.nud(\"DEFINED\", 10, ({ bp }) => \"defined\")\n\n\t\t.led(\"AND\", 5, ({ left, bp }) => {\n\t\t\tconst expr = parser.parse({ terminals: [bp - 1] });\n\t\t\treturn (obj: any, vars: object) => left(obj, vars) && expr(obj, vars);\n\t\t})\n\t\t.led(\"OR\", 5, ({ left, token, bp }) => {\n\t\t\tconst expr = parser.parse({ terminals: [bp - 1] });\n\t\t\treturn (obj: any, vars: object) => left(obj, vars) || expr(obj, vars);\n\t\t})\n\t\t.led(\"COMMA\", 1, ({ left, token, bp }) => {\n\t\t\tconst expr: any = parser.parse({ terminals: [bp - 1] });\n\t\t\tif (Array.isArray(expr)) {\n\t\t\t\treturn [left, ...expr];\n\t\t\t}\n\t\t\treturn [left, expr];\n\t\t})\n\t\t.nud(\"(\", 100, (t) => {\n\t\t\tconst expr: any = parser.parse({ terminals: [\")\"] });\n\t\t\treturn expr;\n\t\t})\n\t\t.led(\"(\", 100, ({ left, bp }) => {\n\t\t\tconst expr = parser.parse();\n\t\t\tlexer.expect(\")\");\n\t\t\treturn (obj: any, vars: object) => {\n\t\t\t\tif (Array.isArray(obj)) {\n\t\t\t\t\treturn obj.some((item) => {\n\t\t\t\t\t\tconst value = resolveValue(item, left);\n\t\t\t\t\t\tif (value) {\n\t\t\t\t\t\t\treturn expr(value, vars);\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tconst value = resolveValue(obj, left);\n\t\t\t\tif (value) {\n\t\t\t\t\tif (Array.isArray(value)) {\n\t\t\t\t\t\treturn value.some((item) => expr(item, vars));\n\t\t\t\t\t}\n\n\t\t\t\t\treturn expr(value, vars);\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t};\n\t\t})\n\t\t.bp(\")\", 0)\n\t\t.led(\"=\", 20, ({ left, bp }) => {\n\t\t\tconst expr = parser.parse({ terminals: [bp - 1] });\n\t\t\tvalidateSymbol(expr);\n\n\t\t\treturn (obj: any, vars: VariableMap) => {\n\t\t\t\tif (Array.isArray(obj)) {\n\t\t\t\t\treturn obj.some((item) => {\n\t\t\t\t\t\tconst value = resolveValue(item, left);\n\t\t\t\t\t\tconst other = resolveSymbol(expr, vars);\n\t\t\t\t\t\tif (Array.isArray(value)) {\n\t\t\t\t\t\t\treturn !!value.some((elem) => elem === other);\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn value === other;\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tconst resolvedValue = resolveValue(obj, left);\n\t\t\t\tconst resolvedSymbol = resolveSymbol(expr, vars);\n\t\t\t\tif (Array.isArray(resolvedValue)) {\n\t\t\t\t\treturn !!resolvedValue.some((elem) => elem === resolvedSymbol);\n\t\t\t\t}\n\t\t\t\treturn resolvedValue === resolvedSymbol;\n\t\t\t};\n\t\t})\n\t\t.led(\"!=\", 20, ({ left, bp }) => {\n\t\t\tconst expr = parser.parse({ terminals: [bp - 1] });\n\t\t\tvalidateSymbol(expr);\n\t\t\treturn (obj: any, vars: VariableMap) =>\n\t\t\t\tresolveValue(obj, left) !== resolveSymbol(expr, vars);\n\t\t})\n\t\t.led(\">\", 20, ({ left, bp }) => {\n\t\t\tconst expr = parser.parse({ terminals: [bp - 1] });\n\t\t\tvalidateSymbol(expr);\n\n\t\t\treturn (obj: any, vars: object) =>\n\t\t\t\tresolveValue(obj, left) > resolveSymbol(expr, vars);\n\t\t})\n\t\t.led(\">=\", 20, ({ left, bp }) => {\n\t\t\tconst expr = parser.parse({ terminals: [bp - 1] });\n\t\t\tvalidateSymbol(expr);\n\n\t\t\treturn (obj: any, vars: object) =>\n\t\t\t\tresolveValue(obj, left) >= resolveSymbol(expr, vars);\n\t\t})\n\t\t.led(\"<\", 20, ({ left, bp }) => {\n\t\t\tconst expr = parser.parse({ terminals: [bp - 1] });\n\t\t\tvalidateSymbol(expr);\n\n\t\t\treturn (obj: any, vars: object) =>\n\t\t\t\tresolveValue(obj, left) < resolveSymbol(expr, vars);\n\t\t})\n\t\t.led(\"<=\", 20, ({ left, bp }) => {\n\t\t\tconst expr = parser.parse({ terminals: [bp - 1] });\n\t\t\tvalidateSymbol(expr);\n\n\t\t\treturn (obj: any, vars: object) =>\n\t\t\t\tresolveValue(obj, left) <= resolveSymbol(expr, vars);\n\t\t})\n\t\t.led(\"IS\", 20, ({ left, bp }) => {\n\t\t\tlet invert = false;\n\n\t\t\t// Peek if this is a `is not` statement\n\t\t\tconst next = lexer.peek();\n\t\t\tif (next.type === \"NOT\") {\n\t\t\t\tinvert = true;\n\t\t\t\tlexer.next();\n\t\t\t}\n\n\t\t\tconst expr: any = parser.parse({ terminals: [bp - 1] });\n\n\t\t\tswitch (expr) {\n\t\t\t\tcase \"empty\": {\n\t\t\t\t\tif (!invert) {\n\t\t\t\t\t\treturn (obj: any, vars: VariableMap) => {\n\t\t\t\t\t\t\tconst val = resolveValue(obj, left);\n\t\t\t\t\t\t\treturn val.length === 0;\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t\treturn (obj: any, vars: VariableMap) => {\n\t\t\t\t\t\tconst val = resolveValue(obj, left);\n\t\t\t\t\t\treturn val.length !== 0;\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\tcase \"defined\": {\n\t\t\t\t\tif (!invert) {\n\t\t\t\t\t\treturn (obj: any, vars: VariableMap) => {\n\t\t\t\t\t\t\tconst val = resolveValue(obj, left);\n\t\t\t\t\t\t\treturn val !== undefined;\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t\treturn (obj: any, vars: VariableMap) => {\n\t\t\t\t\t\tconst val = resolveValue(obj, left);\n\t\t\t\t\t\treturn val === undefined;\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\tdefault: {\n\t\t\t\t\tthrow new Error(\"Unexpected\");\n\t\t\t\t}\n\t\t\t}\n\t\t})\n\t\t.led(\"IN\", 20, ({ left, bp }) => {\n\t\t\tconst firstToken = lexer.peek();\n\t\t\tconst expr = parser.parse({ terminals: [bp - 1] });\n\n\t\t\t// IN can be a single value or a list of values\n\t\t\tif (firstToken.match === \"(\") {\n\t\t\t\tlexer.expect(\")\");\n\t\t\t}\n\n\t\t\treturn (obj: any, vars: object) => {\n\t\t\t\tlet symbols = expr;\n\t\t\t\tif (!Array.isArray(symbols)) {\n\t\t\t\t\tsymbols = [expr];\n\t\t\t\t}\n\n\t\t\t\t// The expression can be a list of variables, like\n\t\t\t\t// :value_1, :value_2, but it can also be one variable\n\t\t\t\t// containing a list, like :values.\n\t\t\t\t// So to support both we just flatten the list.\n\t\t\t\tconst inValues = symbols.flatMap((item: TypeSymbol) =>\n\t\t\t\t\tresolveSymbol(item, vars),\n\t\t\t\t);\n\t\t\t\tconst value = resolveValue(obj, left);\n\n\t\t\t\tif (Array.isArray(value)) {\n\t\t\t\t\treturn inValues.some((inValue: any) => value.includes(inValue));\n\t\t\t\t}\n\n\t\t\t\treturn inValues.includes(value);\n\t\t\t};\n\t\t})\n\t\t.led(\"MATCHES_IGNORE_CASE\", 20, ({ left, bp }) => {\n\t\t\tconst expr = parser.parse({ terminals: [bp - 1] });\n\t\t\tvalidateSymbol(expr);\n\n\t\t\treturn (obj: any, vars: VariableMap) => {\n\t\t\t\tconst value = resolveValue(obj, left);\n\t\t\t\tconst other = resolveSymbol(expr, vars);\n\n\t\t\t\tif (typeof value !== \"string\") {\n\t\t\t\t\tthrow new PredicateError(\n\t\t\t\t\t\t`The field '${left.value}' does not support this expression.`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\treturn value.toLowerCase() === other.toLowerCase();\n\t\t\t};\n\t\t})\n\t\t.led(\"WITHIN\", 20, ({ left, bp }) => {\n\t\t\tconst type = lexer.next();\n\n\t\t\tif (type.match !== \"circle\") {\n\t\t\t\tthrow new PredicateError(\n\t\t\t\t\t`Invalid input '${type.match}', expected circle`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tlexer.expect(\"(\");\n\t\t\tconst expr = parser.parse({ terminals: [\")\"] });\n\t\t\tlexer.expect(\")\");\n\n\t\t\treturn (obj: any, vars: object) => {\n\t\t\t\tconst value = resolveValue(obj, left);\n\t\t\t\tif (!value) return false;\n\n\t\t\t\tconst maxDistance = resolveSymbol(expr[2], vars);\n\t\t\t\tconst distance = haversineDistance(\n\t\t\t\t\t{\n\t\t\t\t\t\tlongitude: value[0],\n\t\t\t\t\t\tlatitude: value[1],\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tlongitude: resolveSymbol(expr[0], vars),\n\t\t\t\t\t\tlatitude: resolveSymbol(expr[1], vars),\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t\treturn distance <= maxDistance;\n\t\t\t};\n\t\t})\n\t\t.led(\"CONTAINS\", 20, ({ left, bp }) => {\n\t\t\tconst keyword = lexer.next();\n\n\t\t\tlet expr = parser.parse();\n\t\t\tif (!Array.isArray(expr)) {\n\t\t\t\texpr = [expr];\n\t\t\t}\n\n\t\t\treturn (obj: any, vars: object) => {\n\t\t\t\tconst value = resolveValue(obj, left);\n\n\t\t\t\tif (!Array.isArray(value)) {\n\t\t\t\t\tthrow new PredicateError(\n\t\t\t\t\t\t`The field '${left.value}' does not support this expression.`,\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tconst array = expr.map((item: TypeSymbol) => resolveSymbol(item, vars));\n\t\t\t\tif (keyword.type === \"ALL\") {\n\t\t\t\t\treturn array.every((item: any) => value.includes(item));\n\t\t\t\t}\n\t\t\t\treturn array.some((item: any) => value.includes(item));\n\t\t\t};\n\t\t})\n\n\t\t.build();\n\n\tconst result = parser.parse();\n\n\tif (typeof result !== \"function\") {\n\t\tconst lines = predicate.split(\"\\n\");\n\t\tconst column = lines[lines.length - 1].length;\n\n\t\tthrow new PredicateError(\n\t\t\t`Unexpected end of input, expected SphereIdentifierChar, comparison operator, not, in, contains, is, within or matches (line ${lines.length}, column ${column})`,\n\t\t);\n\t}\n\treturn result;\n};\n","import type {\n\tFacetResults,\n\tFilteredFacetResult,\n\tInvalidInputError,\n\tProduct,\n\tProductProjection,\n\tProductProjectionPagedSearchResponse,\n\tQueryParam,\n\tRangeFacetResult,\n\tTermFacetResult,\n} from \"@commercetools/platform-sdk\";\nimport type { Config } from \"./config.ts\";\nimport { CommercetoolsError } from \"./exceptions.ts\";\nimport { nestedLookup } from \"./helpers.ts\";\nimport type {\n\tFilterExpression,\n\tRangeExpression,\n} from \"./lib/projectionSearchFilter.ts\";\nimport {\n\tgenerateFacetFunc,\n\tgetVariants,\n\tparseFilterExpression,\n\tresolveVariantValue,\n} from \"./lib/projectionSearchFilter.ts\";\nimport { ReviewStatisticsService } from \"./lib/review-statistics.ts\";\nimport { applyPriceSelector } from \"./priceSelector.ts\";\nimport type { AbstractStorage } from \"./storage/index.ts\";\nimport type { Writable } from \"./types.ts\";\n\nexport type ProductProjectionSearchParams = {\n\tfuzzy?: boolean;\n\tfuzzyLevel?: number;\n\tmarkMatchingVariants?: boolean;\n\tstaged?: boolean;\n\tfilter?: string[];\n\t\"filter.facets\"?: string[];\n\t\"filter.query\"?: string[];\n\tfacet?: string | string[];\n\tsort?: string | string[];\n\tlimit?: number;\n\toffset?: number;\n\twithTotal?: boolean;\n\tpriceCurrency?: string;\n\tpriceCountry?: string;\n\tpriceCustomerGroup?: string;\n\tpriceChannel?: string;\n\tlocaleProjection?: string;\n\tstoreProjection?: string;\n\texpand?: string | string[];\n\t[key: string]: QueryParam;\n};\n\nexport class ProductProjectionSearch {\n\tprotected _storage: AbstractStorage;\n\tprotected _reviewStatisticsService: ReviewStatisticsService;\n\n\tconstructor(config: Config) {\n\t\tthis._storage = config.storage;\n\t\tthis._reviewStatisticsService = new ReviewStatisticsService(config.storage);\n\t}\n\n\tsearch(\n\t\tprojectKey: string,\n\t\tparams: ProductProjectionSearchParams,\n\t): ProductProjectionPagedSearchResponse {\n\t\tlet resources = this._storage\n\t\t\t.all(projectKey, \"product\")\n\t\t\t.map((r) => this.transform(r, params.staged ?? false, projectKey))\n\t\t\t.filter((p) => {\n\t\t\t\tif (!(params.staged ?? false)) {\n\t\t\t\t\treturn p.published;\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t});\n\n\t\tconst markMatchingVariant = params.markMatchingVariants ?? false;\n\n\t\t// Apply the priceSelector\n\t\tapplyPriceSelector(resources, {\n\t\t\tcountry: params.priceCountry,\n\t\t\tchannel: params.priceChannel,\n\t\t\tcustomerGroup: params.priceCustomerGroup,\n\t\t\tcurrency: params.priceCurrency,\n\t\t});\n\n\t\t// Apply filters pre faceting\n\t\tif (params.filter) {\n\t\t\ttry {\n\t\t\t\tconst filters = params.filter.map(parseFilterExpression);\n\n\t\t\t\t// Filters can modify the output. So clone the resources first.\n\t\t\t\tresources = resources.filter((resource) =>\n\t\t\t\t\tfilters.every((f) => f(resource, markMatchingVariant)),\n\t\t\t\t);\n\t\t\t} catch (err) {\n\t\t\t\tthrow new CommercetoolsError<InvalidInputError>(\n\t\t\t\t\t{\n\t\t\t\t\t\tcode: \"InvalidInput\",\n\t\t\t\t\t\tmessage: (err as any).message,\n\t\t\t\t\t},\n\t\t\t\t\t400,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\t// TODO: Calculate facets\n\t\tconst facets = this.getFacets(params, resources);\n\n\t\t// Apply filters post facetting\n\t\tif (params[\"filter.query\"]) {\n\t\t\ttry {\n\t\t\t\tconst filters = params[\"filter.query\"].map(parseFilterExpression);\n\t\t\t\tresources = resources.filter((resource) =>\n\t\t\t\t\tfilters.every((f) => f(resource, markMatchingVariant)),\n\t\t\t\t);\n\t\t\t} catch (err) {\n\t\t\t\tthrow new CommercetoolsError<InvalidInputError>(\n\t\t\t\t\t{\n\t\t\t\t\t\tcode: \"InvalidInput\",\n\t\t\t\t\t\tmessage: (err as any).message,\n\t\t\t\t\t},\n\t\t\t\t\t400,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\t// Expand the resources\n\t\tif (params.expand !== undefined) {\n\t\t\tresources = resources.map((resource) =>\n\t\t\t\tthis._storage.expand(projectKey, resource, params.expand),\n\t\t\t);\n\t\t}\n\n\t\t// Create a slice for the pagination. If we were working with large datasets\n\t\t// then we should have done this before transforming. But that isn't the\n\t\t// goal of this library. So lets keep it simple.\n\t\tconst totalResults = resources.length;\n\t\tconst offset = params.offset || 0;\n\t\tconst limit = params.limit || 20;\n\t\tconst results = resources.slice(offset, offset + limit);\n\n\t\treturn {\n\t\t\tcount: totalResults,\n\t\t\ttotal: results.length,\n\t\t\toffset: offset,\n\t\t\tlimit: limit,\n\t\t\tresults: results,\n\t\t\tfacets: facets,\n\t\t};\n\t}\n\n\ttransform(\n\t\tproduct: Product,\n\t\tstaged: boolean,\n\t\tprojectKey: string,\n\t): ProductProjection {\n\t\tconst obj = !staged\n\t\t\t? product.masterData.current\n\t\t\t: product.masterData.staged;\n\n\t\t// Calculate review statistics for this product\n\t\tconst reviewRatingStatistics =\n\t\t\tthis._reviewStatisticsService.calculateProductReviewStatistics(\n\t\t\t\tprojectKey,\n\t\t\t\tproduct.id,\n\t\t\t);\n\n\t\treturn {\n\t\t\tid: product.id,\n\t\t\tcreatedAt: product.createdAt,\n\t\t\tattributes: obj.attributes,\n\t\t\tlastModifiedAt: product.lastModifiedAt,\n\t\t\tversion: product.version,\n\t\t\tname: obj.name,\n\t\t\tkey: product.key,\n\t\t\tdescription: obj.description,\n\t\t\tmetaDescription: obj.metaDescription,\n\t\t\tslug: obj.slug,\n\t\t\tcategories: obj.categories,\n\t\t\tmasterVariant: obj.masterVariant,\n\t\t\tvariants: obj.variants,\n\t\t\tproductType: product.productType,\n\t\t\thasStagedChanges: product.masterData.hasStagedChanges,\n\t\t\tpublished: product.masterData.published,\n\t\t\treviewRatingStatistics,\n\t\t};\n\t}\n\n\tgetFacets(\n\t\tparams: ProductProjectionSearchParams,\n\t\tproducts: ProductProjection[],\n\t): FacetResults {\n\t\tif (!params.facet) return {};\n\t\tconst result: FacetResults = {};\n\n\t\tconst regexp = new RegExp(/ counting products$/);\n\t\tfor (let facet of params.facet) {\n\t\t\tlet countProducts = false;\n\t\t\tif (facet.endsWith(\" counting products\")) {\n\t\t\t\tfacet = facet.replace(regexp, \"\");\n\t\t\t\tcountProducts = true;\n\t\t\t}\n\n\t\t\tconst expression = generateFacetFunc(facet);\n\n\t\t\t// Term Facet\n\t\t\tif (expression.type === \"TermExpression\") {\n\t\t\t\tresult[facet] = this.termFacet(\n\t\t\t\t\texpression.source,\n\t\t\t\t\tproducts,\n\t\t\t\t\tcountProducts,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Range Facet\n\t\t\tif (expression.type === \"RangeExpression\") {\n\t\t\t\tresult[expression.source] = this.rangeFacet(\n\t\t\t\t\texpression.source,\n\t\t\t\t\texpression.children,\n\t\t\t\t\tproducts,\n\t\t\t\t\tcountProducts,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// FilteredFacet\n\t\t\tif (expression.type === \"FilterExpression\") {\n\t\t\t\tresult[expression.source] = this.filterFacet(\n\t\t\t\t\texpression.source,\n\t\t\t\t\texpression.children,\n\t\t\t\t\tproducts,\n\t\t\t\t\tcountProducts,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\treturn result;\n\t}\n\n\t/**\n\t * TODO: This implemention needs the following additional features:\n\t * - counting products\n\t * - correct dataType\n\t */\n\ttermFacet(\n\t\tfacet: string,\n\t\tproducts: ProductProjection[],\n\t\tcountProducts: boolean,\n\t): TermFacetResult {\n\t\tconst result: Writable<TermFacetResult> = {\n\t\t\ttype: \"terms\",\n\t\t\tdataType: \"text\",\n\t\t\tmissing: 0,\n\t\t\ttotal: 0,\n\t\t\tother: 0,\n\t\t\tterms: [],\n\t\t};\n\t\tconst terms: Record<any, number> = {};\n\n\t\tif (facet.startsWith(\"variants.\")) {\n\t\t\tfor (const p of products) {\n\t\t\t\tconst variants = getVariants(p);\n\t\t\t\tfor (const v of variants) {\n\t\t\t\t\tresult.total++;\n\n\t\t\t\t\tlet value = resolveVariantValue(v, facet);\n\t\t\t\t\tif (value === undefined) {\n\t\t\t\t\t\tresult.missing++;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif (typeof value === \"number\") {\n\t\t\t\t\t\t\tvalue = Number(value).toFixed(1);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tterms[value] = value in terms ? terms[value] + 1 : 1;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tfor (const p of products) {\n\t\t\t\tconst value = nestedLookup(p, facet);\n\t\t\t\tresult.total++;\n\t\t\t\tif (value === undefined) {\n\t\t\t\t\tresult.missing++;\n\t\t\t\t} else {\n\t\t\t\t\tterms[value] = value in terms ? terms[value] + 1 : 1;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tfor (const term in terms) {\n\t\t\tresult.terms.push({\n\t\t\t\tterm: term as any,\n\t\t\t\tcount: terms[term],\n\t\t\t});\n\t\t}\n\n\t\treturn result;\n\t}\n\n\tfilterFacet(\n\t\tsource: string,\n\t\tfilters: FilterExpression[] | undefined,\n\t\tproducts: ProductProjection[],\n\t\tcountProducts: boolean,\n\t): FilteredFacetResult {\n\t\tlet count = 0;\n\t\tif (source.startsWith(\"variants.\")) {\n\t\t\tfor (const p of products) {\n\t\t\t\tfor (const v of getVariants(p)) {\n\t\t\t\t\tconst val = resolveVariantValue(v, source);\n\t\t\t\t\tif (filters?.some((f) => f.match(val))) {\n\t\t\t\t\t\tcount++;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tthrow new Error(\"not supported\");\n\t\t}\n\n\t\treturn {\n\t\t\ttype: \"filter\",\n\t\t\tcount: count,\n\t\t};\n\t}\n\n\trangeFacet(\n\t\tsource: string,\n\t\tranges: RangeExpression[] | undefined,\n\t\tproducts: ProductProjection[],\n\t\tcountProducts: boolean,\n\t): RangeFacetResult {\n\t\tconst counts =\n\t\t\tranges?.map((range) => {\n\t\t\t\tif (source.startsWith(\"variants.\")) {\n\t\t\t\t\tconst values: number[] = [];\n\t\t\t\t\tfor (const p of products) {\n\t\t\t\t\t\tfor (const v of getVariants(p)) {\n\t\t\t\t\t\t\tconst val = resolveVariantValue(v, source);\n\t\t\t\t\t\t\tif (val === undefined) {\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (range.match(val)) {\n\t\t\t\t\t\t\t\tvalues.push(val);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tconst numValues = values.length;\n\t\t\t\t\treturn {\n\t\t\t\t\t\ttype: \"double\",\n\t\t\t\t\t\tfrom: range.start || 0,\n\t\t\t\t\t\tfromStr: range.start !== null ? Number(range.start).toFixed(1) : \"\",\n\t\t\t\t\t\tto: range.stop || 0,\n\t\t\t\t\t\ttoStr: range.stop !== null ? Number(range.stop).toFixed(1) : \"\",\n\t\t\t\t\t\tcount: numValues,\n\t\t\t\t\t\t// totalCount: 0,\n\t\t\t\t\t\ttotal: values.reduce((a, b) => a + b, 0),\n\t\t\t\t\t\tmin: numValues > 0 ? Math.min(...values) : 0,\n\t\t\t\t\t\tmax: numValues > 0 ? Math.max(...values) : 0,\n\t\t\t\t\t\tmean: numValues > 0 ? mean(values) : 0,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\tthrow new Error(\"not supported\");\n\t\t\t}) || [];\n\t\tconst data: RangeFacetResult = {\n\t\t\ttype: \"range\",\n\t\t\t// @ts-expect-error\n\t\t\tdataType: \"number\",\n\t\t\tranges: counts,\n\t\t};\n\t\treturn data;\n\t}\n}\n\nconst mean = (arr: number[]) => {\n\tlet total = 0;\n\tfor (let i = 0; i < arr.length; i++) {\n\t\ttotal += arr[i];\n\t}\n\treturn total / arr.length;\n};\n","import type {\n\tInvalidInputError,\n\tProductDraft,\n\tProductProjection,\n\tQueryParam,\n} from \"@commercetools/platform-sdk\";\nimport type { Config } from \"#src/config.ts\";\nimport { CommercetoolsError } from \"#src/exceptions.ts\";\nimport { parseQueryExpression } from \"../lib/predicateParser.ts\";\nimport { applyPriceSelector } from \"../priceSelector.ts\";\nimport { ProductProjectionSearch } from \"../product-projection-search.ts\";\nimport type { GetParams, RepositoryContext } from \"./abstract.ts\";\nimport { AbstractResourceRepository } from \"./abstract.ts\";\n\nexport type ProductProjectionQueryParams = {\n\tstaged?: boolean;\n\tpriceCurrency?: string;\n\tpriceCountry?: string;\n\tpriceCustomerGroup?: string;\n\tpriceChannel?: string;\n\tlocaleProjection?: string;\n\tstoreProjection?: string;\n\texpand?: string | string[];\n\tsort?: string | string[];\n\tlimit?: number;\n\toffset?: number;\n\twithTotal?: boolean;\n\twhere?: string | string[];\n\t[key: string]: QueryParam;\n};\n\nexport class ProductProjectionRepository extends AbstractResourceRepository<\"product-projection\"> {\n\tprotected _searchService: ProductProjectionSearch;\n\n\tconstructor(config: Config) {\n\t\tsuper(\"product-projection\", config);\n\t\tthis._searchService = new ProductProjectionSearch(config);\n\t}\n\n\tcreate(context: RepositoryContext, draft: ProductDraft): ProductProjection {\n\t\tthrow new Error(\"No valid action\");\n\t}\n\n\tget(\n\t\tcontext: RepositoryContext,\n\t\tid: string,\n\t\tparams: GetParams = {},\n\t): ProductProjection | null {\n\t\tconst resource = this._storage.get(\n\t\t\tcontext.projectKey,\n\t\t\t\"product\",\n\t\t\tid,\n\t\t\tparams,\n\t\t);\n\t\tif (resource) {\n\t\t\treturn this._searchService.transform(resource, false, context.projectKey);\n\t\t}\n\t\treturn null;\n\t}\n\n\tquery(context: RepositoryContext, params: ProductProjectionQueryParams = {}) {\n\t\tlet resources = this._storage\n\t\t\t.all(context.projectKey, \"product\")\n\t\t\t.map((r) =>\n\t\t\t\tthis._searchService.transform(\n\t\t\t\t\tr,\n\t\t\t\t\tparams.staged ?? false,\n\t\t\t\t\tcontext.projectKey,\n\t\t\t\t),\n\t\t\t)\n\t\t\t.filter((p) => {\n\t\t\t\tif (!(params.staged ?? false)) {\n\t\t\t\t\treturn p.published;\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t});\n\n\t\t// Apply predicates\n\t\tif (params.where) {\n\t\t\tconst variableMap: Record<string, QueryParam> = {};\n\t\t\tfor (const [k, v] of Object.entries(params)) {\n\t\t\t\tif (k.startsWith(\"var.\")) {\n\t\t\t\t\tvariableMap[k.substring(4)] = v;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tconst filterFunc = parseQueryExpression(params.where);\n\t\t\t\tresources = resources.filter((resource) =>\n\t\t\t\t\tfilterFunc(resource, variableMap),\n\t\t\t\t);\n\t\t\t} catch (err) {\n\t\t\t\tthrow new CommercetoolsError<InvalidInputError>(\n\t\t\t\t\t{\n\t\t\t\t\t\tcode: \"InvalidInput\",\n\t\t\t\t\t\tmessage: (err as any).message,\n\t\t\t\t\t},\n\t\t\t\t\t400,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\t// We do this after the filtering, since the docs mention:\n\t\t// Only available when Price selection is used. Cannot be used in a Query\n\t\t// Predicate.\n\t\tapplyPriceSelector(\n\t\t\tresources,\n\t\t\t{\n\t\t\t\tcountry: params.priceCountry,\n\t\t\t\tchannel: params.priceChannel,\n\t\t\t\tcustomerGroup: params.priceCustomerGroup,\n\t\t\t\tcurrency: params.priceCurrency,\n\t\t\t},\n\t\t\ttrue,\n\t\t);\n\n\t\t// Expand the resources\n\t\tif (params.expand !== undefined) {\n\t\t\tresources = resources.map((resource) =>\n\t\t\t\tthis._storage.expand(context.projectKey, resource, params.expand),\n\t\t\t);\n\t\t}\n\n\t\t// Create a slice for the pagination. If we were working with large datasets\n\t\t// then we should have done this before transforming. But that isn't the\n\t\t// goal of this library. So lets keep it simple.\n\t\tconst totalResults = resources.length;\n\t\tconst offset = params.offset || 0;\n\t\tconst limit = params.limit || 20;\n\t\tconst results = resources.slice(offset, offset + limit);\n\n\t\treturn {\n\t\t\tcount: totalResults,\n\t\t\ttotal: results.length,\n\t\t\toffset: offset,\n\t\t\tlimit: limit,\n\t\t\tresults: results,\n\t\t};\n\t}\n\n\tsearch(context: RepositoryContext, query: ProductProjectionQueryParams) {\n\t\treturn this._searchService.search(context.projectKey, query);\n\t}\n}\n","import type {\n\tProductSelection,\n\tProductSelectionChangeNameAction,\n\tProductSelectionDraft,\n\tProductSelectionSetCustomTypeAction,\n\tProductSelectionUpdateAction,\n} from \"@commercetools/platform-sdk\";\nimport type { Config } from \"#src/config.ts\";\nimport { createCustomFields } from \"#src/repositories/helpers.ts\";\nimport { getBaseResourceProperties } from \"../helpers.ts\";\nimport type { Writable } from \"../types.ts\";\nimport type { RepositoryContext, UpdateHandlerInterface } from \"./abstract.ts\";\nimport {\n\tAbstractResourceRepository,\n\tAbstractUpdateHandler,\n} from \"./abstract.ts\";\n\nexport class ProductSelectionRepository extends AbstractResourceRepository<\"product-selection\"> {\n\tconstructor(config: Config) {\n\t\tsuper(\"product-selection\", config);\n\t\tthis.actions = new ProductSelectionUpdateHandler(this._storage);\n\t}\n\n\tcreate(\n\t\tcontext: RepositoryContext,\n\t\tdraft: ProductSelectionDraft,\n\t): ProductSelection {\n\t\tconst resource: ProductSelection = {\n\t\t\t...getBaseResourceProperties(),\n\t\t\tproductCount: 0,\n\t\t\tkey: draft.key,\n\t\t\tname: draft.name,\n\t\t\tmode: \"Individual\",\n\t\t};\n\t\treturn this.saveNew(context, resource);\n\t}\n}\n\nclass ProductSelectionUpdateHandler\n\textends AbstractUpdateHandler\n\timplements\n\t\tPartial<\n\t\t\tUpdateHandlerInterface<ProductSelection, ProductSelectionUpdateAction>\n\t\t>\n{\n\tchangeName(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<ProductSelection>,\n\t\t{ name }: ProductSelectionChangeNameAction,\n\t) {\n\t\tresource.name = name;\n\t}\n\n\tsetCustomType(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<ProductSelection>,\n\t\t{ type, fields }: ProductSelectionSetCustomTypeAction,\n\t) {\n\t\tif (type) {\n\t\t\tresource.custom = createCustomFields(\n\t\t\t\t{ type, fields },\n\t\t\t\tcontext.projectKey,\n\t\t\t\tthis._storage,\n\t\t\t);\n\t\t} else {\n\t\t\tresource.custom = undefined;\n\t\t}\n\t}\n}\n","import type {\n\tAttributeDefinition,\n\tAttributeDefinitionDraft,\n\tAttributeType,\n\tProductType,\n\tProductTypeAddAttributeDefinitionAction,\n\tProductTypeChangeAttributeOrderByNameAction,\n\tProductTypeChangeLabelAction,\n\tProductTypeChangeLocalizedEnumValueLabelAction,\n\tProductTypeDraft,\n\tProductTypeRemoveAttributeDefinitionAction,\n\tProductTypeRemoveEnumValuesAction,\n\tProductTypeUpdateAction,\n} from \"@commercetools/platform-sdk\";\nimport type { Config } from \"#src/config.ts\";\nimport { getBaseResourceProperties } from \"../helpers.ts\";\nimport type { Writable } from \"../types.ts\";\nimport type { RepositoryContext, UpdateHandlerInterface } from \"./abstract.ts\";\nimport {\n\tAbstractResourceRepository,\n\tAbstractUpdateHandler,\n} from \"./abstract.ts\";\n\nexport class ProductTypeRepository extends AbstractResourceRepository<\"product-type\"> {\n\tconstructor(config: Config) {\n\t\tsuper(\"product-type\", config);\n\t\tthis.actions = new ProductTypeUpdateHandler(config.storage);\n\t}\n\n\tcreate(context: RepositoryContext, draft: ProductTypeDraft): ProductType {\n\t\tconst resource: ProductType = {\n\t\t\t...getBaseResourceProperties(),\n\t\t\tkey: draft.key,\n\t\t\tname: draft.name,\n\t\t\tdescription: draft.description,\n\t\t\tattributes: (draft.attributes ?? []).map((a) =>\n\t\t\t\tattributeDefinitionFromAttributeDefinitionDraft(context, a),\n\t\t\t),\n\t\t};\n\n\t\treturn this.saveNew(context, resource);\n\t}\n}\n\nconst attributeDefinitionFromAttributeDefinitionDraft = (\n\t_context: RepositoryContext,\n\tdraft: AttributeDefinitionDraft,\n): AttributeDefinition => ({\n\t...draft,\n\tlevel: draft.level ?? \"Variant\",\n\tattributeConstraint: draft.attributeConstraint ?? \"None\",\n\tinputHint: draft.inputHint ?? \"SingleLine\",\n\tinputTip:\n\t\tdraft.inputTip && Object.keys(draft.inputTip).length > 0\n\t\t\t? draft.inputTip\n\t\t\t: undefined,\n\tisSearchable: draft.isSearchable ?? true,\n});\n\nclass ProductTypeUpdateHandler\n\textends AbstractUpdateHandler\n\timplements\n\t\tPartial<UpdateHandlerInterface<ProductType, ProductTypeUpdateAction>>\n{\n\taddAttributeDefinition(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<ProductType>,\n\t\t{ attribute }: ProductTypeAddAttributeDefinitionAction,\n\t) {\n\t\tresource.attributes?.push(\n\t\t\tattributeDefinitionFromAttributeDefinitionDraft(context, attribute),\n\t\t);\n\t}\n\n\tchangeAttributeOrderByName(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<ProductType>,\n\t\t{ attributeNames }: ProductTypeChangeAttributeOrderByNameAction,\n\t) {\n\t\tconst attrs = new Map(\n\t\t\tresource.attributes?.map((item) => [item.name, item]),\n\t\t);\n\t\tconst result: AttributeDefinition[] = [];\n\t\tlet current = resource.attributes;\n\n\t\tattributeNames.forEach((attrName) => {\n\t\t\tconst attr = attrs.get(attrName);\n\t\t\tif (attr === undefined) {\n\t\t\t\tthrow new Error(\"New attr\");\n\t\t\t}\n\t\t\tresult.push(attr);\n\n\t\t\t// Remove from current items\n\t\t\tcurrent = current?.filter((f) => f.name !== attrName);\n\t\t});\n\n\t\tresource.attributes = result;\n\t\t// Add attrs which were not specified in the order as last items. Not\n\t\t// sure if this follows commercetools\n\t\tif (current) {\n\t\t\tresource.attributes.push(...current);\n\t\t}\n\t}\n\n\tchangeLabel(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<ProductType>,\n\t\t{ attributeName, label }: ProductTypeChangeLabelAction,\n\t) {\n\t\tresource.attributes?.forEach((value) => {\n\t\t\tif (value.name === attributeName) {\n\t\t\t\tvalue.label = label;\n\t\t\t}\n\t\t});\n\t}\n\n\tchangeLocalizedEnumValueLabel(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<ProductType>,\n\t\t{ attributeName, newValue }: ProductTypeChangeLocalizedEnumValueLabelAction,\n\t) {\n\t\tconst updateAttributeType = (type: Writable<AttributeType>) => {\n\t\t\tswitch (type.name) {\n\t\t\t\tcase \"lenum\":\n\t\t\t\t\ttype.values.forEach((v) => {\n\t\t\t\t\t\tif (v.key === newValue.key) {\n\t\t\t\t\t\t\tv.label = newValue.label;\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t\treturn;\n\t\t\t\tcase \"set\":\n\t\t\t\t\tupdateAttributeType(type.elementType);\n\t\t\t\t\treturn;\n\t\t\t}\n\t\t};\n\n\t\tresource.attributes?.forEach((value) => {\n\t\t\tif (value.name === attributeName) {\n\t\t\t\tupdateAttributeType(value.type);\n\t\t\t}\n\t\t});\n\t}\n\n\tremoveAttributeDefinition(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<ProductType>,\n\t\t{ name }: ProductTypeRemoveAttributeDefinitionAction,\n\t) {\n\t\tresource.attributes = resource.attributes?.filter((f) => f.name !== name);\n\t}\n\n\tremoveEnumValues(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<ProductType>,\n\t\t{ attributeName, keys }: ProductTypeRemoveEnumValuesAction,\n\t) {\n\t\tresource.attributes?.forEach((attr) => {\n\t\t\tif (attr.name === attributeName) {\n\t\t\t\tif (attr.type.name === \"enum\") {\n\t\t\t\t\tattr.type.values = attr.type.values.filter(\n\t\t\t\t\t\t(v) => !keys.includes(v.key),\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tif (attr.type.name === \"set\") {\n\t\t\t\t\tif (attr.type.elementType.name === \"enum\") {\n\t\t\t\t\t\tattr.type.elementType.values = attr.type.elementType.values.filter(\n\t\t\t\t\t\t\t(v) => !keys.includes(v.key),\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t}\n}\n","import type {\n\tProject,\n\tProjectChangeBusinessUnitSearchStatusAction,\n\tProjectChangeBusinessUnitStatusOnCreationAction,\n\tProjectChangeCartsConfigurationAction,\n\tProjectChangeCountriesAction,\n\tProjectChangeCountryTaxRateFallbackEnabledAction,\n\tProjectChangeCurrenciesAction,\n\tProjectChangeCustomerSearchStatusAction,\n\tProjectChangeLanguagesAction,\n\tProjectChangeMessagesConfigurationAction,\n\tProjectChangeNameAction,\n\tProjectChangeOrderSearchStatusAction,\n\tProjectChangePriceRoundingModeAction,\n\tProjectChangeProductSearchIndexingEnabledAction,\n\tProjectChangeShoppingListsConfigurationAction,\n\tProjectChangeTaxRoundingModeAction,\n\tProjectSetExternalOAuthAction,\n\tProjectSetShippingRateInputTypeAction,\n\tProjectUpdateAction,\n} from \"@commercetools/platform-sdk\";\nimport type { ProjectSetBusinessUnitAssociateRoleOnCreationAction } from \"@commercetools/platform-sdk/dist/declarations/src/generated/models/project\";\nimport type { Config } from \"#src/config.ts\";\nimport { maskSecretValue } from \"../lib/masking.ts\";\nimport type { Writable } from \"../types.ts\";\nimport type { RepositoryContext, UpdateHandlerInterface } from \"./abstract.ts\";\nimport { AbstractRepository, AbstractUpdateHandler } from \"./abstract.ts\";\n\nexport class ProjectRepository extends AbstractRepository<Project> {\n\tconstructor(config: Config) {\n\t\tsuper(config);\n\t\tthis.actions = new ProjectUpdateHandler(config.storage);\n\t}\n\n\tget(context: RepositoryContext): Project | null {\n\t\tconst resource = this._storage.getProject(context.projectKey);\n\t\treturn this.postProcessResource(context, resource);\n\t}\n\n\tpostProcessResource(context: RepositoryContext, resource: Project): Project {\n\t\tif (resource) {\n\t\t\treturn maskSecretValue(resource, \"externalOAuth.authorizationHeader\");\n\t\t}\n\t\treturn resource;\n\t}\n\n\tsaveNew(context: RepositoryContext, resource: Writable<Project>) {\n\t\tresource.version = 1;\n\t\tthis._storage.saveProject(resource);\n\t}\n\n\tsaveUpdate(context: RepositoryContext, version: number, resource: Project) {\n\t\tthis._storage.saveProject(resource);\n\t}\n}\n\nclass ProjectUpdateHandler\n\textends AbstractUpdateHandler\n\timplements Partial<UpdateHandlerInterface<Project, ProjectUpdateAction>>\n{\n\tchangeCartsConfiguration(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Project>,\n\t\t{ cartsConfiguration }: ProjectChangeCartsConfigurationAction,\n\t) {\n\t\tresource.carts = cartsConfiguration || {\n\t\t\tcountryTaxRateFallbackEnabled: false,\n\t\t\tdeleteDaysAfterLastModification: 90,\n\t\t\tpriceRoundingMode: \"HalfEven\",\n\t\t\ttaxRoundingMode: \"HalfEven\",\n\t\t};\n\t}\n\n\tchangeShoppingListsConfiguration(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Project>,\n\t\t{\n\t\t\tshoppingListsConfiguration,\n\t\t}: ProjectChangeShoppingListsConfigurationAction,\n\t) {\n\t\tresource.shoppingLists = shoppingListsConfiguration || {\n\t\t\tdeleteDaysAfterLastModification: 90,\n\t\t};\n\t}\n\n\tchangeCountries(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Project>,\n\t\t{ countries }: ProjectChangeCountriesAction,\n\t) {\n\t\tresource.countries = countries;\n\t}\n\n\tchangeCountryTaxRateFallbackEnabled(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Project>,\n\t\t{\n\t\t\tcountryTaxRateFallbackEnabled,\n\t\t}: ProjectChangeCountryTaxRateFallbackEnabledAction,\n\t) {\n\t\tresource.carts.countryTaxRateFallbackEnabled =\n\t\t\tcountryTaxRateFallbackEnabled;\n\t}\n\n\tchangePriceRoundingMode(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Project>,\n\t\t{ priceRoundingMode }: ProjectChangePriceRoundingModeAction,\n\t) {\n\t\tresource.carts.priceRoundingMode = priceRoundingMode;\n\t}\n\n\tchangeTaxRoundingMode(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Project>,\n\t\t{ taxRoundingMode }: ProjectChangeTaxRoundingModeAction,\n\t) {\n\t\tresource.carts.taxRoundingMode = taxRoundingMode;\n\t}\n\n\tchangeCurrencies(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Project>,\n\t\t{ currencies }: ProjectChangeCurrenciesAction,\n\t) {\n\t\tresource.currencies = currencies;\n\t}\n\n\tchangeCustomerSearchStatus(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Project>,\n\t\t{ status }: ProjectChangeCustomerSearchStatusAction,\n\t) {\n\t\tif (!resource.searchIndexing?.customers) {\n\t\t\tthrow new Error(\"Invalid project state\");\n\t\t}\n\t\tresource.searchIndexing.customers.status = status;\n\t\tresource.searchIndexing.customers.lastModifiedAt = new Date().toISOString();\n\t}\n\n\tchangeBusinessUnitSearchStatus(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Project>,\n\t\t{ status }: ProjectChangeBusinessUnitSearchStatusAction,\n\t) {\n\t\tif (!resource.searchIndexing?.businessUnits) {\n\t\t\tthrow new Error(\"Invalid project state\");\n\t\t}\n\t\tresource.searchIndexing.businessUnits.status = status;\n\t\tresource.searchIndexing.businessUnits.lastModifiedAt =\n\t\t\tnew Date().toISOString();\n\t}\n\n\tchangeLanguages(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Project>,\n\t\t{ languages }: ProjectChangeLanguagesAction,\n\t) {\n\t\tresource.languages = languages;\n\t}\n\n\tchangeMessagesConfiguration(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Project>,\n\t\t{ messagesConfiguration }: ProjectChangeMessagesConfigurationAction,\n\t) {\n\t\tresource.messages.enabled = messagesConfiguration.enabled;\n\t\tresource.messages.deleteDaysAfterCreation =\n\t\t\tmessagesConfiguration.deleteDaysAfterCreation;\n\t}\n\n\tchangeMyBusinessUnitStatusOnCreation(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Project>,\n\t\t{ status }: ProjectChangeBusinessUnitStatusOnCreationAction,\n\t) {\n\t\tif (resource.businessUnits === undefined) {\n\t\t\tresource.businessUnits = {\n\t\t\t\tmyBusinessUnitStatusOnCreation: \"Inactive\",\n\t\t\t};\n\t\t}\n\n\t\tresource.businessUnits.myBusinessUnitStatusOnCreation = status;\n\t}\n\n\tchangeName(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Project>,\n\t\t{ name }: ProjectChangeNameAction,\n\t) {\n\t\tresource.name = name;\n\t}\n\n\tchangeOrderSearchStatus(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Project>,\n\t\t{ status }: ProjectChangeOrderSearchStatusAction,\n\t) {\n\t\tif (!resource.searchIndexing?.orders) {\n\t\t\tthrow new Error(\"Invalid project state\");\n\t\t}\n\t\tresource.searchIndexing.orders.status = status;\n\t\tresource.searchIndexing.orders.lastModifiedAt = new Date().toISOString();\n\t}\n\n\tchangeProductSearchIndexingEnabled(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Project>,\n\t\t{ enabled, mode }: ProjectChangeProductSearchIndexingEnabledAction,\n\t) {\n\t\tif (mode === \"ProductsSearch\") {\n\t\t\tif (!resource.searchIndexing?.productsSearch) {\n\t\t\t\tthrow new Error(\"Invalid project state\");\n\t\t\t}\n\t\t\tresource.searchIndexing.productsSearch.status = enabled\n\t\t\t\t? \"Activated\"\n\t\t\t\t: \"Deactivated\";\n\t\t\tresource.searchIndexing.productsSearch.lastModifiedAt =\n\t\t\t\tnew Date().toISOString();\n\t\t\treturn;\n\t\t}\n\n\t\tif (!resource.searchIndexing?.products) {\n\t\t\tthrow new Error(\"Invalid project state\");\n\t\t}\n\t\tresource.searchIndexing.products.status = enabled\n\t\t\t? \"Activated\"\n\t\t\t: \"Deactivated\";\n\t\tresource.searchIndexing.products.lastModifiedAt = new Date().toISOString();\n\t}\n\n\tsetExternalOAuth(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Project>,\n\t\t{ externalOAuth }: ProjectSetExternalOAuthAction,\n\t) {\n\t\tresource.externalOAuth = externalOAuth;\n\t}\n\n\tsetMyBusinessUnitAssociateRoleOnCreation(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Project>,\n\t\t{ associateRole }: ProjectSetBusinessUnitAssociateRoleOnCreationAction,\n\t) {\n\t\tif (resource.businessUnits === undefined) {\n\t\t\tresource.businessUnits = {\n\t\t\t\t//Default status, so we set it here also\n\t\t\t\tmyBusinessUnitStatusOnCreation: \"Inactive\",\n\t\t\t};\n\t\t}\n\n\t\tresource.businessUnits.myBusinessUnitAssociateRoleOnCreation = {\n\t\t\ttypeId: associateRole.typeId,\n\t\t\tkey: associateRole.key ?? \"unknown\",\n\t\t};\n\t}\n\n\tsetShippingRateInputType(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Project>,\n\t\t{ shippingRateInputType }: ProjectSetShippingRateInputTypeAction,\n\t) {\n\t\tresource.shippingRateInputType = shippingRateInputType;\n\t}\n}\n","import type {\n\tInvalidJsonInputError,\n\tQuote,\n\tQuoteSetCustomFieldAction,\n\tQuoteSetCustomTypeAction,\n\tQuoteTransitionStateAction,\n\tQuoteUpdateAction,\n\tStateReference,\n} from \"@commercetools/platform-sdk\";\nimport { CommercetoolsError } from \"#src/exceptions.ts\";\nimport type { Writable } from \"#src/types.ts\";\nimport type { RepositoryContext, UpdateHandlerInterface } from \"../abstract.ts\";\nimport { AbstractUpdateHandler } from \"../abstract.ts\";\nimport { getReferenceFromResourceIdentifier } from \"../helpers.ts\";\n\nexport class QuoteUpdateHandler\n\textends AbstractUpdateHandler\n\timplements Partial<UpdateHandlerInterface<Quote, QuoteUpdateAction>>\n{\n\tsetCustomField(\n\t\tcontext: RepositoryContext,\n\t\tresource: Quote,\n\t\t{ name, value }: QuoteSetCustomFieldAction,\n\t) {\n\t\tif (!resource.custom) {\n\t\t\tthrow new Error(\"Resource has no custom field\");\n\t\t}\n\t\tresource.custom.fields[name] = value;\n\t}\n\n\tsetCustomType(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Quote>,\n\t\t{ type, fields }: QuoteSetCustomTypeAction,\n\t) {\n\t\tif (!type) {\n\t\t\tresource.custom = undefined;\n\t\t} else {\n\t\t\tconst resolvedType = this._storage.getByResourceIdentifier(\n\t\t\t\tcontext.projectKey,\n\t\t\t\ttype,\n\t\t\t);\n\t\t\tif (!resolvedType) {\n\t\t\t\tthrow new Error(`Type ${type} not found`);\n\t\t\t}\n\n\t\t\tresource.custom = {\n\t\t\t\ttype: {\n\t\t\t\t\ttypeId: \"type\",\n\t\t\t\t\tid: resolvedType.id,\n\t\t\t\t},\n\t\t\t\tfields: fields || {},\n\t\t\t};\n\t\t}\n\t}\n\n\ttransitionState(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Quote>,\n\t\t{ state, force }: QuoteTransitionStateAction,\n\t) {\n\t\tlet stateReference: StateReference | undefined;\n\t\tif (state) {\n\t\t\tstateReference = getReferenceFromResourceIdentifier<StateReference>(\n\t\t\t\tstate,\n\t\t\t\tcontext.projectKey,\n\t\t\t\tthis._storage,\n\t\t\t);\n\t\t\tresource.state = stateReference;\n\t\t} else {\n\t\t\tthrow new CommercetoolsError<InvalidJsonInputError>(\n\t\t\t\t{\n\t\t\t\t\tcode: \"InvalidJsonInput\",\n\t\t\t\t\tmessage: \"Request body does not contain valid JSON.\",\n\t\t\t\t\tdetailedErrorMessage: \"actions -> state: Missing required value\",\n\t\t\t\t},\n\t\t\t\t400,\n\t\t\t);\n\t\t}\n\n\t\treturn resource;\n\t}\n}\n","import type { Quote, QuoteDraft } from \"@commercetools/platform-sdk\";\nimport type { Config } from \"#src/config.ts\";\nimport { getBaseResourceProperties } from \"#src/helpers.ts\";\nimport type { RepositoryContext } from \"../abstract.ts\";\nimport { AbstractResourceRepository } from \"../abstract.ts\";\nimport { QuoteUpdateHandler } from \"./actions.ts\";\n\nexport class QuoteRepository extends AbstractResourceRepository<\"quote\"> {\n\tconstructor(config: Config) {\n\t\tsuper(\"quote\", config);\n\t\tthis.actions = new QuoteUpdateHandler(config.storage);\n\t}\n\n\tcreate(context: RepositoryContext, draft: QuoteDraft): Quote {\n\t\tconst staged = this._storage.getByResourceIdentifier<\"staged-quote\">(\n\t\t\tcontext.projectKey,\n\t\t\tdraft.stagedQuote,\n\t\t);\n\n\t\tconst cart = this._storage.getByResourceIdentifier<\"cart\">(\n\t\t\tcontext.projectKey,\n\t\t\tstaged.quotationCart,\n\t\t);\n\n\t\tif (!cart.customerId) {\n\t\t\tthrow new Error(\"Cart does not have a customer\");\n\t\t}\n\n\t\tconst resource: Quote = {\n\t\t\t...getBaseResourceProperties(),\n\t\t\tquoteState: \"Accepted\",\n\t\t\tquoteRequest: staged.quoteRequest,\n\t\t\tlineItems: cart.lineItems,\n\t\t\tcustomLineItems: cart.customLineItems,\n\t\t\tcustomer: {\n\t\t\t\ttypeId: \"customer\",\n\t\t\t\tid: cart.customerId,\n\t\t\t},\n\t\t\tstagedQuote: {\n\t\t\t\ttypeId: \"staged-quote\",\n\t\t\t\tid: staged.id,\n\t\t\t},\n\t\t\tpriceRoundingMode: cart.priceRoundingMode,\n\t\t\ttotalPrice: cart.totalPrice,\n\t\t\ttaxedPrice: cart.taxedPrice,\n\t\t\ttaxMode: cart.taxMode,\n\t\t\ttaxRoundingMode: cart.taxRoundingMode,\n\t\t\ttaxCalculationMode: cart.taxCalculationMode,\n\t\t\tbillingAddress: cart.billingAddress,\n\t\t\tshippingAddress: cart.shippingAddress,\n\t\t};\n\n\t\treturn resource;\n\t}\n}\n","import type {\n\tInvalidJsonInputError,\n\tStagedQuote,\n\tStagedQuoteSetCustomFieldAction,\n\tStagedQuoteSetCustomTypeAction,\n\tStagedQuoteTransitionStateAction,\n\tStagedQuoteUpdateAction,\n\tStateReference,\n} from \"@commercetools/platform-sdk\";\nimport { CommercetoolsError } from \"#src/exceptions.ts\";\nimport type { Writable } from \"#src/types.ts\";\nimport type { RepositoryContext, UpdateHandlerInterface } from \"../abstract.ts\";\nimport { AbstractUpdateHandler } from \"../abstract.ts\";\nimport { getReferenceFromResourceIdentifier } from \"../helpers.ts\";\n\nexport class StagedQuoteUpdateHandler\n\textends AbstractUpdateHandler\n\timplements\n\t\tPartial<UpdateHandlerInterface<StagedQuote, StagedQuoteUpdateAction>>\n{\n\tsetCustomField(\n\t\tcontext: RepositoryContext,\n\t\tresource: StagedQuote,\n\t\t{ name, value }: StagedQuoteSetCustomFieldAction,\n\t) {\n\t\tif (!resource.custom) {\n\t\t\tthrow new Error(\"Resource has no custom field\");\n\t\t}\n\t\tresource.custom.fields[name] = value;\n\t}\n\n\tsetCustomType(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<StagedQuote>,\n\t\t{ type, fields }: StagedQuoteSetCustomTypeAction,\n\t) {\n\t\tif (!type) {\n\t\t\tresource.custom = undefined;\n\t\t} else {\n\t\t\tconst resolvedType = this._storage.getByResourceIdentifier(\n\t\t\t\tcontext.projectKey,\n\t\t\t\ttype,\n\t\t\t);\n\t\t\tif (!resolvedType) {\n\t\t\t\tthrow new Error(`Type ${type} not found`);\n\t\t\t}\n\n\t\t\tresource.custom = {\n\t\t\t\ttype: {\n\t\t\t\t\ttypeId: \"type\",\n\t\t\t\t\tid: resolvedType.id,\n\t\t\t\t},\n\t\t\t\tfields: fields || {},\n\t\t\t};\n\t\t}\n\t}\n\n\ttransitionState(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<StagedQuote>,\n\t\t{ state, force }: StagedQuoteTransitionStateAction,\n\t) {\n\t\tlet stateReference: StateReference | undefined;\n\t\tif (state) {\n\t\t\tstateReference = getReferenceFromResourceIdentifier<StateReference>(\n\t\t\t\tstate,\n\t\t\t\tcontext.projectKey,\n\t\t\t\tthis._storage,\n\t\t\t);\n\t\t\tresource.state = stateReference;\n\t\t} else {\n\t\t\tthrow new CommercetoolsError<InvalidJsonInputError>(\n\t\t\t\t{\n\t\t\t\t\tcode: \"InvalidJsonInput\",\n\t\t\t\t\tmessage: \"Request body does not contain valid JSON.\",\n\t\t\t\t\tdetailedErrorMessage: \"actions -> state: Missing required value\",\n\t\t\t\t},\n\t\t\t\t400,\n\t\t\t);\n\t\t}\n\n\t\treturn resource;\n\t}\n}\n","import type {\n\tStagedQuote,\n\tStagedQuoteDraft,\n} from \"@commercetools/platform-sdk\";\nimport type { Config } from \"#src/config.ts\";\nimport { getBaseResourceProperties } from \"#src/helpers.ts\";\nimport type { RepositoryContext } from \"../abstract.ts\";\nimport { AbstractResourceRepository } from \"../abstract.ts\";\nimport { StagedQuoteUpdateHandler } from \"./actions.ts\";\n\nexport class StagedQuoteRepository extends AbstractResourceRepository<\"staged-quote\"> {\n\tconstructor(config: Config) {\n\t\tsuper(\"staged-quote\", config);\n\t\tthis.actions = new StagedQuoteUpdateHandler(config.storage);\n\t}\n\n\tcreate(context: RepositoryContext, draft: StagedQuoteDraft): StagedQuote {\n\t\tconst quoteRequest = this._storage.getByResourceIdentifier<\"quote-request\">(\n\t\t\tcontext.projectKey,\n\t\t\tdraft.quoteRequest,\n\t\t);\n\n\t\tif (!quoteRequest.cart) {\n\t\t\tthrow new Error(\"Cannot find quote request\");\n\t\t}\n\n\t\tconst cart = this._storage.getByResourceIdentifier<\"cart\">(\n\t\t\tcontext.projectKey,\n\t\t\tquoteRequest.cart,\n\t\t);\n\n\t\tconst resource: StagedQuote = {\n\t\t\t...getBaseResourceProperties(),\n\t\t\tstagedQuoteState: \"InProgress\",\n\t\t\tquoteRequest: {\n\t\t\t\ttypeId: \"quote-request\",\n\t\t\t\tid: quoteRequest.id,\n\t\t\t},\n\t\t\tquotationCart: {\n\t\t\t\ttypeId: \"cart\",\n\t\t\t\tid: cart.id,\n\t\t\t},\n\t\t};\n\n\t\treturn resource;\n\t}\n}\n","import type {\n\tRecurrencePolicy,\n\tRecurrencePolicySetDescriptionAction,\n\tRecurrencePolicySetKeyAction,\n\tRecurrencePolicySetNameAction,\n\tRecurrencePolicySetScheduleAction,\n\tRecurrencePolicyUpdateAction,\n} from \"@commercetools/platform-sdk\";\nimport type { Writable } from \"#src/types.ts\";\nimport type { UpdateHandlerInterface } from \"../abstract.ts\";\nimport { AbstractUpdateHandler, type RepositoryContext } from \"../abstract.ts\";\n\nexport class RecurrencePolicyUpdateHandler\n\textends AbstractUpdateHandler\n\timplements\n\t\tPartial<\n\t\t\tUpdateHandlerInterface<RecurrencePolicy, RecurrencePolicyUpdateAction>\n\t\t>\n{\n\tsetKey(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<RecurrencePolicy>,\n\t\t{ key }: RecurrencePolicySetKeyAction,\n\t) {\n\t\tif (key) {\n\t\t\tresource.key = key;\n\t\t}\n\t}\n\n\tsetDescription(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<RecurrencePolicy>,\n\t\t{ description }: RecurrencePolicySetDescriptionAction,\n\t) {\n\t\tresource.description = description;\n\t}\n\n\tsetName(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<RecurrencePolicy>,\n\t\t{ name }: RecurrencePolicySetNameAction,\n\t) {\n\t\tresource.name = name;\n\t}\n\n\tsetSchedule(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<RecurrencePolicy>,\n\t\t{ schedule }: RecurrencePolicySetScheduleAction,\n\t) {\n\t\tresource.schedule = schedule;\n\t}\n}\n","import type {\n\tRecurrencePolicy,\n\tRecurrencePolicyDraft,\n} from \"@commercetools/platform-sdk\";\nimport type { Config } from \"#src/config.ts\";\nimport { getBaseResourceProperties } from \"#src/helpers.ts\";\nimport {\n\tAbstractResourceRepository,\n\ttype RepositoryContext,\n} from \"../abstract.ts\";\nimport { RecurrencePolicyUpdateHandler } from \"./actions.ts\";\n\nexport class RecurrencePolicyRepository extends AbstractResourceRepository<\"recurrence-policy\"> {\n\tconstructor(config: Config) {\n\t\tsuper(\"recurrence-policy\", config);\n\t\tthis.actions = new RecurrencePolicyUpdateHandler(config.storage);\n\t}\n\n\tcreate(\n\t\tcontext: RepositoryContext,\n\t\tdraft: RecurrencePolicyDraft,\n\t): RecurrencePolicy {\n\t\tconst resource: RecurrencePolicy = {\n\t\t\t...getBaseResourceProperties(),\n\t\t\tkey: draft.key,\n\t\t\tname: draft.name,\n\t\t\tdescription: draft.description,\n\t\t\tschedule: draft.schedule,\n\t\t};\n\t\treturn this.saveNew(context, resource);\n\t}\n}\n","import type {\n\tRecurringOrder,\n\tRecurringOrderSetCustomFieldAction,\n\tRecurringOrderSetCustomTypeAction,\n\tRecurringOrderSetExpiresAtAction,\n\tRecurringOrderSetKeyAction,\n\tRecurringOrderSetOrderSkipConfigurationAction,\n\tRecurringOrderSetScheduleAction,\n\tRecurringOrderSetStartsAtAction,\n\tRecurringOrderSetStateAction,\n\tRecurringOrderTransitionStateAction,\n\tRecurringOrderUpdateAction,\n} from \"@commercetools/platform-sdk\";\nimport type { Writable } from \"#src/types.ts\";\nimport type { UpdateHandlerInterface } from \"../abstract.ts\";\nimport { AbstractUpdateHandler, type RepositoryContext } from \"../abstract.ts\";\n\nexport class RecurringOrderUpdateHandler\n\textends AbstractUpdateHandler\n\timplements\n\t\tPartial<UpdateHandlerInterface<RecurringOrder, RecurringOrderUpdateAction>>\n{\n\tsetCustomField(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<RecurringOrder>,\n\t\t{ name, value }: RecurringOrderSetCustomFieldAction,\n\t) {\n\t\tif (!resource.custom) {\n\t\t\tthrow new Error(\"Resource has no custom field\");\n\t\t}\n\t\tif (value === null) {\n\t\t\tdelete resource.custom.fields[name];\n\t\t} else {\n\t\t\tresource.custom.fields[name] = value;\n\t\t}\n\t}\n\n\tsetCustomType(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<RecurringOrder>,\n\t\t{ type, fields }: RecurringOrderSetCustomTypeAction,\n\t) {\n\t\tif (!type) {\n\t\t\tresource.custom = undefined;\n\t\t} else {\n\t\t\tconst resolvedType = this._storage.getByResourceIdentifier(\n\t\t\t\tcontext.projectKey,\n\t\t\t\ttype,\n\t\t\t);\n\t\t\tif (!resolvedType) {\n\t\t\t\tthrow new Error(`Type ${type} not found`);\n\t\t\t}\n\n\t\t\tresource.custom = {\n\t\t\t\ttype: {\n\t\t\t\t\ttypeId: \"type\",\n\t\t\t\t\tid: resolvedType.id,\n\t\t\t\t},\n\t\t\t\tfields: fields || {},\n\t\t\t};\n\t\t}\n\t}\n\n\tsetExpiresAt(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<RecurringOrder>,\n\t\t{ expiresAt }: RecurringOrderSetExpiresAtAction,\n\t) {\n\t\tresource.expiresAt = expiresAt;\n\t}\n\n\tsetKey(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<RecurringOrder>,\n\t\t{ key }: RecurringOrderSetKeyAction,\n\t) {\n\t\tresource.key = key;\n\t}\n\n\tsetOrderSkipConfiguration(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<RecurringOrder>,\n\t\t{\n\t\t\tskipConfiguration,\n\t\t\tupdatedExpiresAt,\n\t\t}: RecurringOrderSetOrderSkipConfigurationAction,\n\t) {\n\t\tif (skipConfiguration) {\n\t\t\tresource.skipConfiguration = {\n\t\t\t\ttype: skipConfiguration.type,\n\t\t\t\ttotalToSkip: skipConfiguration.totalToSkip,\n\t\t\t\tskipped: 0,\n\t\t\t\tlastSkippedAt: undefined,\n\t\t\t};\n\t\t} else {\n\t\t\tresource.skipConfiguration = undefined;\n\t\t}\n\t\tif (updatedExpiresAt !== undefined) {\n\t\t\tresource.expiresAt = updatedExpiresAt;\n\t\t}\n\t}\n\n\tsetSchedule(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<RecurringOrder>,\n\t\t{ recurrencePolicy }: RecurringOrderSetScheduleAction,\n\t) {\n\t\tresource.schedule = {\n\t\t\t...resource.schedule,\n\t\t\t...recurrencePolicy,\n\t\t};\n\t}\n\n\tsetStartsAt(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<RecurringOrder>,\n\t\t{ startsAt }: RecurringOrderSetStartsAtAction,\n\t) {\n\t\tresource.startsAt = startsAt;\n\t}\n\n\tsetRecurringOrderState(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<RecurringOrder>,\n\t\t{ recurringOrderState }: RecurringOrderSetStateAction,\n\t) {\n\t\t// Map the state draft to the actual state\n\t\tswitch (recurringOrderState.type) {\n\t\t\tcase \"active\":\n\t\t\t\tresource.recurringOrderState = \"Active\";\n\t\t\t\tif (recurringOrderState.resumesAt) {\n\t\t\t\t\tresource.resumesAt = recurringOrderState.resumesAt;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase \"canceled\":\n\t\t\t\tresource.recurringOrderState = \"Canceled\";\n\t\t\t\tbreak;\n\t\t\tcase \"expired\":\n\t\t\t\tresource.recurringOrderState = \"Expired\";\n\t\t\t\tbreak;\n\t\t\tcase \"paused\":\n\t\t\t\tresource.recurringOrderState = \"Paused\";\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\ttransitionState(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<RecurringOrder>,\n\t\t{ state, force }: RecurringOrderTransitionStateAction,\n\t) {\n\t\tresource.state = {\n\t\t\ttypeId: \"state\",\n\t\t\tid: state.id!,\n\t\t};\n\t}\n}\n","import assert from \"node:assert\";\nimport type {\n\tRecurringOrder,\n\tRecurringOrderDraft,\n} from \"@commercetools/platform-sdk\";\nimport type { Config } from \"#src/config.ts\";\nimport { getBaseResourceProperties } from \"#src/helpers.ts\";\nimport {\n\tAbstractResourceRepository,\n\ttype RepositoryContext,\n} from \"../abstract.ts\";\nimport { OrderRepository } from \"../order/index.ts\";\nimport { RecurringOrderUpdateHandler } from \"./actions.ts\";\n\nexport class RecurringOrderRepository extends AbstractResourceRepository<\"recurring-order\"> {\n\tconstructor(config: Config) {\n\t\tsuper(\"recurring-order\", config);\n\t\tthis.actions = new RecurringOrderUpdateHandler(config.storage);\n\t}\n\n\tcreate(\n\t\tcontext: RepositoryContext,\n\t\tdraft: RecurringOrderDraft,\n\t): RecurringOrder {\n\t\tassert(draft.cart, \"draft.cart is missing\");\n\n\t\tconst orderRepo = new OrderRepository(this.config);\n\n\t\tconst initialOrder = orderRepo.createFromCart(context, {\n\t\t\tid: draft.cart.id!,\n\t\t\ttypeId: \"cart\",\n\t\t});\n\n\t\tconst resource: RecurringOrder = {\n\t\t\t...getBaseResourceProperties(),\n\t\t\tkey: draft.key,\n\t\t\tcart: {\n\t\t\t\ttypeId: \"cart\",\n\t\t\t\tid: draft.cart.id!,\n\t\t\t},\n\t\t\toriginOrder: {\n\t\t\t\ttypeId: \"order\",\n\t\t\t\tid: initialOrder.id,\n\t\t\t},\n\t\t\tstartsAt: draft.startsAt,\n\t\t\texpiresAt: draft.expiresAt,\n\t\t\trecurringOrderState: \"Active\",\n\t\t\tschedule: { type: \"standard\", intervalUnit: \"month\", value: 1 },\n\t\t};\n\t\treturn this.saveNew(context, resource);\n\t}\n}\n","import type {\n\tChannelReference,\n\tCustomerReference,\n\tProductReference,\n\tReview,\n\tReviewDraft,\n\tReviewSetAuthorNameAction,\n\tReviewSetCustomerAction,\n\tReviewSetCustomFieldAction,\n\tReviewSetCustomTypeAction,\n\tReviewSetKeyAction,\n\tReviewSetLocaleAction,\n\tReviewSetRatingAction,\n\tReviewSetTargetAction,\n\tReviewSetTextAction,\n\tReviewSetTitleAction,\n\tReviewTransitionStateAction,\n\tReviewUpdateAction,\n\tStateReference,\n} from \"@commercetools/platform-sdk\";\nimport type { Config } from \"#src/config.ts\";\nimport { getBaseResourceProperties } from \"../helpers.ts\";\nimport type { Writable } from \"../types.ts\";\nimport type { RepositoryContext, UpdateHandlerInterface } from \"./abstract.ts\";\nimport {\n\tAbstractResourceRepository,\n\tAbstractUpdateHandler,\n} from \"./abstract.ts\";\nimport {\n\tcreateCustomFields,\n\tgetReferenceFromResourceIdentifier,\n} from \"./helpers.ts\";\n\nexport class ReviewRepository extends AbstractResourceRepository<\"review\"> {\n\tconstructor(config: Config) {\n\t\tsuper(\"review\", config);\n\t\tthis.actions = new ReviewUpdateHandler(config.storage);\n\t}\n\n\tcreate(context: RepositoryContext, draft: ReviewDraft): Review {\n\t\tif (!draft.target) throw new Error(\"Missing target\");\n\t\tconst resource: Review = {\n\t\t\t...getBaseResourceProperties(),\n\t\t\tkey: draft.key,\n\t\t\tlocale: draft.locale,\n\t\t\tauthorName: draft.authorName,\n\t\t\ttitle: draft.title,\n\t\t\ttext: draft.text,\n\t\t\trating: draft.rating,\n\t\t\tuniquenessValue: draft.uniquenessValue,\n\t\t\tstate: draft.state\n\t\t\t\t? getReferenceFromResourceIdentifier<StateReference>(\n\t\t\t\t\t\tdraft.state,\n\t\t\t\t\t\tcontext.projectKey,\n\t\t\t\t\t\tthis._storage,\n\t\t\t\t\t)\n\t\t\t\t: undefined,\n\t\t\ttarget: draft.target\n\t\t\t\t? getReferenceFromResourceIdentifier<\n\t\t\t\t\t\tProductReference | ChannelReference\n\t\t\t\t\t>(draft.target, context.projectKey, this._storage)\n\t\t\t\t: undefined,\n\t\t\tincludedInStatistics: true,\n\t\t\tcustom: createCustomFields(\n\t\t\t\tdraft.custom,\n\t\t\t\tcontext.projectKey,\n\t\t\t\tthis._storage,\n\t\t\t),\n\t\t};\n\t\treturn this.saveNew(context, resource);\n\t}\n}\n\nclass ReviewUpdateHandler\n\textends AbstractUpdateHandler\n\timplements UpdateHandlerInterface<Review, ReviewUpdateAction>\n{\n\tsetAuthorName(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Review>,\n\t\t{ authorName }: ReviewSetAuthorNameAction,\n\t) {\n\t\tresource.authorName = authorName;\n\t}\n\n\tsetCustomField(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Review>,\n\t\t{ name, value }: ReviewSetCustomFieldAction,\n\t) {\n\t\tif (!resource.custom) {\n\t\t\tthrow new Error(\"Resource has no custom field\");\n\t\t}\n\t\tresource.custom.fields[name] = value;\n\t}\n\n\tsetCustomType(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Review>,\n\t\t{ type, fields }: ReviewSetCustomTypeAction,\n\t) {\n\t\tif (!type) {\n\t\t\tresource.custom = undefined;\n\t\t} else {\n\t\t\tconst resolvedType = this._storage.getByResourceIdentifier(\n\t\t\t\tcontext.projectKey,\n\t\t\t\ttype,\n\t\t\t);\n\t\t\tif (!resolvedType) {\n\t\t\t\tthrow new Error(`Type ${type} not found`);\n\t\t\t}\n\n\t\t\tresource.custom = {\n\t\t\t\ttype: {\n\t\t\t\t\ttypeId: \"type\",\n\t\t\t\t\tid: resolvedType.id,\n\t\t\t\t},\n\t\t\t\tfields: fields ?? {},\n\t\t\t};\n\t\t}\n\t}\n\n\tsetCustomer(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Review>,\n\t\t{ customer }: ReviewSetCustomerAction,\n\t) {\n\t\tresource.customer = customer\n\t\t\t? getReferenceFromResourceIdentifier<CustomerReference>(\n\t\t\t\t\tcustomer,\n\t\t\t\t\tcontext.projectKey,\n\t\t\t\t\tthis._storage,\n\t\t\t\t)\n\t\t\t: undefined;\n\t}\n\n\tsetKey(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Review>,\n\t\t{ key }: ReviewSetKeyAction,\n\t) {\n\t\tresource.key = key;\n\t}\n\n\tsetLocale(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Review>,\n\t\t{ locale }: ReviewSetLocaleAction,\n\t) {\n\t\tresource.locale = locale;\n\t}\n\n\tsetRating(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Review>,\n\t\t{ rating }: ReviewSetRatingAction,\n\t) {\n\t\tresource.rating = rating;\n\t}\n\n\tsetTarget(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Review>,\n\t\t{ target }: ReviewSetTargetAction,\n\t) {\n\t\tresource.target = getReferenceFromResourceIdentifier<\n\t\t\tProductReference | ChannelReference\n\t\t>(target, context.projectKey, this._storage);\n\t}\n\n\tsetText(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Review>,\n\t\t{ text }: ReviewSetTextAction,\n\t) {\n\t\tresource.text = text;\n\t}\n\n\tsetTitle(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Review>,\n\t\t{ title }: ReviewSetTitleAction,\n\t) {\n\t\tresource.title = title;\n\t}\n\n\ttransitionState(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Review>,\n\t\t{ state }: ReviewTransitionStateAction,\n\t) {\n\t\tresource.state = getReferenceFromResourceIdentifier<StateReference>(\n\t\t\tstate,\n\t\t\tcontext.projectKey,\n\t\t\tthis._storage,\n\t\t);\n\t}\n}\n","import type {\n\tShippingRate,\n\tShippingRateDraft,\n} from \"@commercetools/platform-sdk\";\nimport { createTypedMoney } from \"../helpers.ts\";\n\nexport const transformShippingRate = (\n\trate: ShippingRateDraft,\n): ShippingRate => ({\n\tprice: createTypedMoney(rate.price),\n\tfreeAbove: rate.freeAbove && createTypedMoney(rate.freeAbove),\n\ttiers: rate.tiers || [],\n});\n","import { isDeepStrictEqual } from \"node:util\";\nimport type {\n\tShippingMethod,\n\tShippingMethodAddShippingRateAction,\n\tShippingMethodAddZoneAction,\n\tShippingMethodChangeActiveAction,\n\tShippingMethodChangeIsDefaultAction,\n\tShippingMethodChangeNameAction,\n\tShippingMethodChangeTaxCategoryAction,\n\tShippingMethodRemoveShippingRateAction,\n\tShippingMethodRemoveZoneAction,\n\tShippingMethodSetCustomFieldAction,\n\tShippingMethodSetCustomTypeAction,\n\tShippingMethodSetDescriptionAction,\n\tShippingMethodSetKeyAction,\n\tShippingMethodSetLocalizedDescriptionAction,\n\tShippingMethodSetLocalizedNameAction,\n\tShippingMethodSetPredicateAction,\n\tShippingMethodUpdateAction,\n\tZoneReference,\n} from \"@commercetools/platform-sdk\";\nimport type { Writable } from \"#src/types.ts\";\nimport type { RepositoryContext, UpdateHandlerInterface } from \"../abstract.ts\";\nimport { AbstractUpdateHandler } from \"../abstract.ts\";\nimport {\n\tcreateCustomFields,\n\tgetReferenceFromResourceIdentifier,\n} from \"../helpers.ts\";\nimport { transformShippingRate } from \"./helpers.ts\";\n\nexport class ShippingMethodUpdateHandler\n\textends AbstractUpdateHandler\n\timplements UpdateHandlerInterface<ShippingMethod, ShippingMethodUpdateAction>\n{\n\tchangeTaxCategory: (\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<ShippingMethod>,\n\t\taction: ShippingMethodChangeTaxCategoryAction,\n\t) => void;\n\n\taddShippingRate(\n\t\t_context: RepositoryContext,\n\t\tresource: Writable<ShippingMethod>,\n\t\t{ shippingRate, zone }: ShippingMethodAddShippingRateAction,\n\t) {\n\t\tconst rate = transformShippingRate(shippingRate);\n\n\t\tresource.zoneRates.forEach((zoneRate) => {\n\t\t\tif (zoneRate.zone.id === zone.id) {\n\t\t\t\tzoneRate.shippingRates.push(rate);\n\t\t\t\treturn;\n\t\t\t}\n\t\t});\n\t\tresource.zoneRates.push({\n\t\t\tzone: {\n\t\t\t\ttypeId: \"zone\",\n\t\t\t\tid: zone.id!,\n\t\t\t},\n\t\t\tshippingRates: [rate],\n\t\t});\n\t}\n\n\taddZone(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<ShippingMethod>,\n\t\t{ zone }: ShippingMethodAddZoneAction,\n\t) {\n\t\tconst zoneReference = getReferenceFromResourceIdentifier<ZoneReference>(\n\t\t\tzone,\n\t\t\tcontext.projectKey,\n\t\t\tthis._storage,\n\t\t);\n\n\t\tif (resource.zoneRates === undefined) {\n\t\t\tresource.zoneRates = [];\n\t\t}\n\n\t\tresource.zoneRates.push({\n\t\t\tzone: zoneReference,\n\t\t\tshippingRates: [],\n\t\t});\n\t}\n\n\tchangeActive(\n\t\t_context: RepositoryContext,\n\t\tresource: Writable<ShippingMethod>,\n\t\t{ active }: ShippingMethodChangeActiveAction,\n\t) {\n\t\tresource.active = active;\n\t}\n\n\tchangeIsDefault(\n\t\t_context: RepositoryContext,\n\t\tresource: Writable<ShippingMethod>,\n\t\t{ isDefault }: ShippingMethodChangeIsDefaultAction,\n\t) {\n\t\tresource.isDefault = isDefault;\n\t}\n\n\tchangeName(\n\t\t_context: RepositoryContext,\n\t\tresource: Writable<ShippingMethod>,\n\t\t{ name }: ShippingMethodChangeNameAction,\n\t) {\n\t\tresource.name = name;\n\t}\n\n\tremoveShippingRate(\n\t\t_context: RepositoryContext,\n\t\tresource: Writable<ShippingMethod>,\n\t\t{ shippingRate, zone }: ShippingMethodRemoveShippingRateAction,\n\t) {\n\t\tconst rate = transformShippingRate(shippingRate);\n\n\t\tresource.zoneRates.forEach((zoneRate) => {\n\t\t\tif (zoneRate.zone.id === zone.id) {\n\t\t\t\tzoneRate.shippingRates = zoneRate.shippingRates.filter(\n\t\t\t\t\t(otherRate) => !isDeepStrictEqual(rate, otherRate),\n\t\t\t\t);\n\t\t\t}\n\t\t});\n\t}\n\n\tremoveZone(\n\t\t_context: RepositoryContext,\n\t\tresource: Writable<ShippingMethod>,\n\t\t{ zone }: ShippingMethodRemoveZoneAction,\n\t) {\n\t\tresource.zoneRates = resource.zoneRates.filter(\n\t\t\t(zoneRate) => zoneRate.zone.id !== zone.id,\n\t\t);\n\t}\n\n\tsetCustomField(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<ShippingMethod>,\n\t\t{ name, value }: ShippingMethodSetCustomFieldAction,\n\t) {\n\t\tif (!resource.custom) {\n\t\t\treturn;\n\t\t}\n\t\tif (value === null) {\n\t\t\tdelete resource.custom.fields[name];\n\t\t} else {\n\t\t\tresource.custom.fields[name] = value;\n\t\t}\n\t}\n\n\tsetCustomType(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<ShippingMethod>,\n\t\t{ type, fields }: ShippingMethodSetCustomTypeAction,\n\t) {\n\t\tif (type) {\n\t\t\tresource.custom = createCustomFields(\n\t\t\t\t{ type, fields },\n\t\t\t\tcontext.projectKey,\n\t\t\t\tthis._storage,\n\t\t\t);\n\t\t} else {\n\t\t\tresource.custom = undefined;\n\t\t}\n\t}\n\n\tsetDescription(\n\t\t_context: RepositoryContext,\n\t\tresource: Writable<ShippingMethod>,\n\t\t{ description }: ShippingMethodSetDescriptionAction,\n\t) {\n\t\tresource.description = description;\n\t}\n\n\tsetKey(\n\t\t_context: RepositoryContext,\n\t\tresource: Writable<ShippingMethod>,\n\t\t{ key }: ShippingMethodSetKeyAction,\n\t) {\n\t\tresource.key = key;\n\t}\n\n\tsetLocalizedDescription(\n\t\t_context: RepositoryContext,\n\t\tresource: Writable<ShippingMethod>,\n\t\t{ localizedDescription }: ShippingMethodSetLocalizedDescriptionAction,\n\t) {\n\t\tresource.localizedDescription = localizedDescription;\n\t}\n\n\tsetLocalizedName(\n\t\t_context: RepositoryContext,\n\t\tresource: Writable<ShippingMethod>,\n\t\t{ localizedName }: ShippingMethodSetLocalizedNameAction,\n\t) {\n\t\tresource.localizedName = localizedName;\n\t}\n\n\tsetPredicate(\n\t\t_context: RepositoryContext,\n\t\tresource: Writable<ShippingMethod>,\n\t\t{ predicate }: ShippingMethodSetPredicateAction,\n\t) {\n\t\tresource.predicate = predicate;\n\t}\n}\n","import type {\n\tShippingMethod,\n\tShippingMethodDraft,\n\tZoneRate,\n\tZoneRateDraft,\n\tZoneReference,\n} from \"@commercetools/platform-sdk\";\nimport type { Config } from \"#src/config.ts\";\nimport { getBaseResourceProperties } from \"../../helpers.ts\";\nimport { getShippingMethodsMatchingCart } from \"../../shipping.ts\";\nimport type { GetParams, RepositoryContext } from \"../abstract.ts\";\nimport { AbstractResourceRepository } from \"../abstract.ts\";\nimport {\n\tcreateCustomFields,\n\tgetReferenceFromResourceIdentifier,\n} from \"../helpers.ts\";\nimport { ShippingMethodUpdateHandler } from \"./actions.ts\";\nimport { transformShippingRate } from \"./helpers.ts\";\n\nexport class ShippingMethodRepository extends AbstractResourceRepository<\"shipping-method\"> {\n\tconstructor(config: Config) {\n\t\tsuper(\"shipping-method\", config);\n\t\tthis.actions = new ShippingMethodUpdateHandler(config.storage);\n\t}\n\n\tcreate(\n\t\tcontext: RepositoryContext,\n\t\tdraft: ShippingMethodDraft,\n\t): ShippingMethod {\n\t\tconst resource: ShippingMethod = {\n\t\t\t...getBaseResourceProperties(),\n\t\t\t...draft,\n\t\t\tactive: draft.active ?? true,\n\t\t\ttaxCategory: getReferenceFromResourceIdentifier(\n\t\t\t\tdraft.taxCategory,\n\t\t\t\tcontext.projectKey,\n\t\t\t\tthis._storage,\n\t\t\t),\n\t\t\tzoneRates: draft.zoneRates?.map((z) =>\n\t\t\t\tthis._transformZoneRateDraft(context, z),\n\t\t\t),\n\t\t\tcustom: createCustomFields(\n\t\t\t\tdraft.custom,\n\t\t\t\tcontext.projectKey,\n\t\t\t\tthis._storage,\n\t\t\t),\n\t\t};\n\t\treturn this.saveNew(context, resource);\n\t}\n\n\t/*\n\t * Retrieves all the ShippingMethods that can ship to the shipping address of\n\t * the given Cart. Each ShippingMethod contains exactly one ShippingRate with\n\t * the flag isMatching set to true. This ShippingRate is used when the\n\t * ShippingMethod is added to the Cart.\n\t */\n\tpublic matchingCart(\n\t\tcontext: RepositoryContext,\n\t\tcartId: string,\n\t\tparams: GetParams = {},\n\t) {\n\t\tconst cart = this._storage.get(context.projectKey, \"cart\", cartId);\n\t\tif (!cart) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\treturn getShippingMethodsMatchingCart(context, this._storage, cart, params);\n\t}\n\n\tprivate _transformZoneRateDraft(\n\t\tcontext: RepositoryContext,\n\t\tdraft: ZoneRateDraft,\n\t): ZoneRate {\n\t\treturn {\n\t\t\t...draft,\n\t\t\tzone: getReferenceFromResourceIdentifier<ZoneReference>(\n\t\t\t\tdraft.zone,\n\t\t\t\tcontext.projectKey,\n\t\t\t\tthis._storage,\n\t\t\t),\n\t\t\tshippingRates: draft.shippingRates?.map(transformShippingRate),\n\t\t};\n\t}\n}\n","import type {\n\tGeneralError,\n\tProduct,\n\tProductPagedQueryResponse,\n\tShoppingList,\n\tShoppingListAddLineItemAction,\n\tShoppingListChangeLineItemQuantityAction,\n\tShoppingListChangeNameAction,\n\tShoppingListLineItem,\n\tShoppingListRemoveLineItemAction,\n\tShoppingListSetAnonymousIdAction,\n\tShoppingListSetCustomerAction,\n\tShoppingListSetCustomFieldAction,\n\tShoppingListSetCustomTypeAction,\n\tShoppingListSetDeleteDaysAfterLastModificationAction,\n\tShoppingListSetDescriptionAction,\n\tShoppingListSetKeyAction,\n\tShoppingListSetSlugAction,\n\tShoppingListSetStoreAction,\n\tShoppingListUpdateAction,\n} from \"@commercetools/platform-sdk\";\nimport { v4 as uuidv4 } from \"uuid\";\nimport { CommercetoolsError } from \"#src/exceptions.ts\";\nimport type { Writable } from \"../../types.ts\";\nimport type { RepositoryContext, UpdateHandlerInterface } from \"../abstract.ts\";\nimport { AbstractUpdateHandler } from \"../abstract.ts\";\n\nexport class ShoppingListUpdateHandler\n\textends AbstractUpdateHandler\n\timplements\n\t\tPartial<UpdateHandlerInterface<ShoppingList, ShoppingListUpdateAction>>\n{\n\taddLineItem(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<ShoppingList>,\n\t\t{\n\t\t\tproductId,\n\t\t\tvariantId,\n\t\t\tsku,\n\t\t\tquantity = 1,\n\t\t\taddedAt,\n\t\t\tkey,\n\t\t}: ShoppingListAddLineItemAction,\n\t) {\n\t\tlet product: Product | null = null;\n\n\t\tif (productId) {\n\t\t\t// Fetch product and variant by ID\n\t\t\tproduct = this._storage.get(context.projectKey, \"product\", productId, {});\n\t\t} else if (sku) {\n\t\t\t// Fetch product and variant by SKU\n\t\t\tconst items = this._storage.query(context.projectKey, \"product\", {\n\t\t\t\twhere: [\n\t\t\t\t\t`masterData(current(masterVariant(sku=\"${sku}\"))) or masterData(current(variants(sku=\"${sku}\")))`,\n\t\t\t\t],\n\t\t\t}) as ProductPagedQueryResponse;\n\n\t\t\tif (items.count === 1) {\n\t\t\t\tproduct = items.results[0];\n\t\t\t}\n\t\t}\n\n\t\tif (!product) {\n\t\t\t// Check if product is found\n\t\t\tthrow new CommercetoolsError<GeneralError>({\n\t\t\t\tcode: \"General\",\n\t\t\t\tmessage: sku\n\t\t\t\t\t? `A product containing a variant with SKU '${sku}' not found.`\n\t\t\t\t\t: `A product with ID '${productId}' not found.`,\n\t\t\t});\n\t\t}\n\n\t\tlet varId: number | undefined = variantId;\n\t\tif (sku) {\n\t\t\tvarId = [\n\t\t\t\tproduct.masterData.current.masterVariant,\n\t\t\t\t...product.masterData.current.variants,\n\t\t\t].find((x) => x.sku === sku)?.id;\n\t\t}\n\t\tif (!varId) {\n\t\t\tvarId = product.masterData.current.masterVariant.id;\n\t\t}\n\n\t\tconst alreadyAdded = resource.lineItems.some(\n\t\t\t(x) => x.productId === product?.id && x.variantId === varId,\n\t\t);\n\t\tif (alreadyAdded) {\n\t\t\t// increase quantity and update total price\n\t\t\tresource.lineItems.forEach((x) => {\n\t\t\t\tif (x.productId === product?.id && x.variantId === varId) {\n\t\t\t\t\tx.quantity += quantity;\n\t\t\t\t}\n\t\t\t});\n\t\t} else {\n\t\t\t// add line item\n\t\t\tresource.lineItems.push({\n\t\t\t\taddedAt: addedAt ? addedAt : new Date().toISOString(),\n\t\t\t\tid: uuidv4(),\n\t\t\t\tkey,\n\t\t\t\tproductId: product.id,\n\t\t\t\tproductSlug: product.masterData.current.slug,\n\t\t\t\tproductType: product.productType,\n\t\t\t\tname: product.masterData.current.name,\n\t\t\t\tvariantId: varId,\n\t\t\t\tquantity,\n\t\t\t\tpublished: Boolean(product.masterData.current),\n\t\t\t});\n\t\t}\n\t}\n\n\tchangeLineItemQuantity(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<ShoppingList>,\n\t\t{\n\t\t\tlineItemId,\n\t\t\tlineItemKey,\n\t\t\tquantity,\n\t\t}: ShoppingListChangeLineItemQuantityAction,\n\t) {\n\t\tlet lineItem: Writable<ShoppingListLineItem> | undefined;\n\n\t\tif (lineItemId) {\n\t\t\tlineItem = resource.lineItems.find((x) => x.id === lineItemId);\n\t\t\tif (!lineItem) {\n\t\t\t\tthrow new CommercetoolsError<GeneralError>({\n\t\t\t\t\tcode: \"General\",\n\t\t\t\t\tmessage: `A line item with ID '${lineItemId}' not found.`,\n\t\t\t\t});\n\t\t\t}\n\t\t} else if (lineItemKey) {\n\t\t\tlineItem = resource.lineItems.find((x) => x.id === lineItemId);\n\t\t\tif (!lineItem) {\n\t\t\t\tthrow new CommercetoolsError<GeneralError>({\n\t\t\t\t\tcode: \"General\",\n\t\t\t\t\tmessage: `A line item with Key '${lineItemKey}' not found.`,\n\t\t\t\t});\n\t\t\t}\n\t\t} else {\n\t\t\tthrow new CommercetoolsError<GeneralError>({\n\t\t\t\tcode: \"General\",\n\t\t\t\tmessage: \"Either lineItemid or lineItemKey needs to be provided.\",\n\t\t\t});\n\t\t}\n\n\t\tif (quantity === 0) {\n\t\t\t// delete line item\n\t\t\tresource.lineItems = resource.lineItems.filter(\n\t\t\t\t(x) => x.id !== lineItemId,\n\t\t\t);\n\t\t} else {\n\t\t\tresource.lineItems.forEach((x) => {\n\t\t\t\tif (x.id === lineItemId && quantity) {\n\t\t\t\t\tx.quantity = quantity;\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t}\n\n\tchangeName(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<ShoppingList>,\n\t\t{ name }: ShoppingListChangeNameAction,\n\t) {\n\t\tresource.name = name;\n\t}\n\n\tremoveLineItem(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<ShoppingList>,\n\t\t{ lineItemId, quantity }: ShoppingListRemoveLineItemAction,\n\t) {\n\t\tconst lineItem = resource.lineItems.find((x) => x.id === lineItemId);\n\t\tif (!lineItem) {\n\t\t\t// Check if product is found\n\t\t\tthrow new CommercetoolsError<GeneralError>({\n\t\t\t\tcode: \"General\",\n\t\t\t\tmessage: `A line item with ID '${lineItemId}' not found.`,\n\t\t\t});\n\t\t}\n\n\t\tconst shouldDelete = !quantity || quantity >= lineItem.quantity;\n\t\tif (shouldDelete) {\n\t\t\t// delete line item\n\t\t\tresource.lineItems = resource.lineItems.filter(\n\t\t\t\t(x) => x.id !== lineItemId,\n\t\t\t);\n\t\t} else {\n\t\t\t// decrease quantity and update total price\n\t\t\tresource.lineItems.forEach((x) => {\n\t\t\t\tif (x.id === lineItemId && quantity) {\n\t\t\t\t\tx.quantity -= quantity;\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t}\n\n\tsetAnonymousId(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<ShoppingList>,\n\t\t{ anonymousId }: ShoppingListSetAnonymousIdAction,\n\t) {\n\t\tresource.anonymousId = anonymousId;\n\t}\n\n\tsetCustomer(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<ShoppingList>,\n\t\t{ customer }: ShoppingListSetCustomerAction,\n\t) {\n\t\tif (customer?.key) {\n\t\t\tthrow new Error(\"set customer on shoppinglist by key not implemented\");\n\t\t}\n\t\tif (customer?.id) {\n\t\t\tresource.customer = { typeId: \"customer\", id: customer.id };\n\t\t}\n\t}\n\n\tsetCustomField(\n\t\tcontext: RepositoryContext,\n\t\tresource: ShoppingList,\n\t\t{ name, value }: ShoppingListSetCustomFieldAction,\n\t) {\n\t\tif (!resource.custom) {\n\t\t\tthrow new Error(\"Resource has no custom field\");\n\t\t}\n\t\tresource.custom.fields[name] = value;\n\t}\n\n\tsetCustomType(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<ShoppingList>,\n\t\t{ type, fields }: ShoppingListSetCustomTypeAction,\n\t) {\n\t\tif (!type) {\n\t\t\tresource.custom = undefined;\n\t\t} else {\n\t\t\tconst resolvedType = this._storage.getByResourceIdentifier(\n\t\t\t\tcontext.projectKey,\n\t\t\t\ttype,\n\t\t\t);\n\t\t\tif (!resolvedType) {\n\t\t\t\tthrow new Error(`Type ${type} not found`);\n\t\t\t}\n\n\t\t\tresource.custom = {\n\t\t\t\ttype: {\n\t\t\t\t\ttypeId: \"type\",\n\t\t\t\t\tid: resolvedType.id,\n\t\t\t\t},\n\t\t\t\tfields: fields || {},\n\t\t\t};\n\t\t}\n\t}\n\n\tsetDeleteDaysAfterLastModification(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<ShoppingList>,\n\t\t{\n\t\t\tdeleteDaysAfterLastModification,\n\t\t}: ShoppingListSetDeleteDaysAfterLastModificationAction,\n\t) {\n\t\tresource.deleteDaysAfterLastModification = deleteDaysAfterLastModification;\n\t}\n\n\tsetDescription(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<ShoppingList>,\n\t\t{ description }: ShoppingListSetDescriptionAction,\n\t) {\n\t\tresource.description = description;\n\t}\n\n\tsetKey(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<ShoppingList>,\n\t\t{ key }: ShoppingListSetKeyAction,\n\t) {\n\t\tresource.key = key;\n\t}\n\n\tsetSlug(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<ShoppingList>,\n\t\t{ slug }: ShoppingListSetSlugAction,\n\t) {\n\t\tresource.slug = slug;\n\t}\n\n\tsetStore(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<ShoppingList>,\n\t\t{ store }: ShoppingListSetStoreAction,\n\t) {\n\t\tif (store?.key) {\n\t\t\tresource.store = { typeId: \"store\", key: store.key };\n\t\t}\n\t\tif (store?.id) {\n\t\t\tthrow new Error(\"set store on shoppinglist by id not implemented\");\n\t\t}\n\t}\n}\n","import type {\n\tCustomerReference,\n\tLineItemDraft,\n\tProductPagedQueryResponse,\n\tShoppingList,\n\tShoppingListDraft,\n\tShoppingListLineItem,\n} from \"@commercetools/platform-sdk\";\nimport type { Config } from \"#src/config.ts\";\nimport { getBaseResourceProperties } from \"../../helpers.ts\";\nimport type { Writable } from \"../../types.ts\";\nimport type { RepositoryContext } from \"../abstract.ts\";\nimport { AbstractResourceRepository } from \"../abstract.ts\";\nimport {\n\tcreateCustomFields,\n\tgetBusinessUnitKeyReference,\n\tgetReferenceFromResourceIdentifier,\n\tgetStoreKeyReference,\n} from \"../helpers.ts\";\nimport { ShoppingListUpdateHandler } from \"./actions.ts\";\n\nexport class ShoppingListRepository extends AbstractResourceRepository<\"shopping-list\"> {\n\tconstructor(config: Config) {\n\t\tsuper(\"shopping-list\", config);\n\t\tthis.actions = new ShoppingListUpdateHandler(config.storage);\n\t}\n\n\tcreate(context: RepositoryContext, draft: ShoppingListDraft): ShoppingList {\n\t\tconst lineItems =\n\t\t\tdraft.lineItems?.map((draftLineItem) =>\n\t\t\t\tthis.draftLineItemtoLineItem(context.projectKey, draftLineItem),\n\t\t\t) ?? [];\n\n\t\tconst resource: ShoppingList = {\n\t\t\t...getBaseResourceProperties(),\n\t\t\t...draft,\n\t\t\tcustom: createCustomFields(\n\t\t\t\tdraft.custom,\n\t\t\t\tcontext.projectKey,\n\t\t\t\tthis._storage,\n\t\t\t),\n\t\t\ttextLineItems: [],\n\t\t\tlineItems,\n\t\t\tcustomer: draft.customer\n\t\t\t\t? getReferenceFromResourceIdentifier<CustomerReference>(\n\t\t\t\t\t\tdraft.customer,\n\t\t\t\t\t\tcontext.projectKey,\n\t\t\t\t\t\tthis._storage,\n\t\t\t\t\t)\n\t\t\t\t: undefined,\n\t\t\tstore: draft.store\n\t\t\t\t? getStoreKeyReference(draft.store, context.projectKey, this._storage)\n\t\t\t\t: undefined,\n\t\t\tbusinessUnit: draft.businessUnit\n\t\t\t\t? getBusinessUnitKeyReference(\n\t\t\t\t\t\tdraft.businessUnit,\n\t\t\t\t\t\tcontext.projectKey,\n\t\t\t\t\t\tthis._storage,\n\t\t\t\t\t)\n\t\t\t\t: undefined,\n\t\t};\n\t\treturn this.saveNew(context, resource);\n\t}\n\n\tdraftLineItemtoLineItem = (\n\t\tprojectKey: string,\n\t\tdraftLineItem: LineItemDraft,\n\t): ShoppingListLineItem => {\n\t\tconst { sku, productId, variantId } = draftLineItem;\n\n\t\tconst lineItem: Writable<ShoppingListLineItem> = {\n\t\t\t...getBaseResourceProperties(),\n\t\t\t...draftLineItem,\n\t\t\taddedAt: draftLineItem.addedAt ?? \"\",\n\t\t\tproductId: draftLineItem.productId ?? \"\",\n\t\t\tname: {},\n\t\t\tvariantId,\n\t\t\tpublished: true,\n\t\t\tquantity: draftLineItem.quantity ?? 1,\n\t\t\tproductType: { typeId: \"product-type\", id: \"\" },\n\t\t\tcustom: createCustomFields(\n\t\t\t\tdraftLineItem.custom,\n\t\t\t\tprojectKey,\n\t\t\t\tthis._storage,\n\t\t\t),\n\t\t};\n\n\t\tif (productId && variantId) {\n\t\t\treturn lineItem;\n\t\t}\n\n\t\tif (sku) {\n\t\t\tconst items = this._storage.query(projectKey, \"product\", {\n\t\t\t\twhere: [\n\t\t\t\t\t`masterData(current(masterVariant(sku=\"${sku}\"))) or masterData(current(variants(sku=\"${sku}\")))`,\n\t\t\t\t],\n\t\t\t}) as ProductPagedQueryResponse;\n\n\t\t\tif (items.count === 0) {\n\t\t\t\tthrow new Error(`Product with sku ${sku} not found`);\n\t\t\t}\n\n\t\t\tconst product = items.results[0];\n\t\t\tconst allVariants = [\n\t\t\t\tproduct.masterData.current.masterVariant,\n\t\t\t\t...product.masterData.current.variants,\n\t\t\t];\n\t\t\tconst variantId = allVariants.find((e) => e.sku === sku)?.id;\n\t\t\tlineItem.variantId = variantId;\n\t\t\tlineItem.productId = product.id;\n\t\t\treturn lineItem;\n\t\t}\n\n\t\tif (productId) {\n\t\t\tconst items = this._storage.query(projectKey, \"product\", {\n\t\t\t\twhere: [`id=\"${productId}\"`],\n\t\t\t}) as ProductPagedQueryResponse;\n\n\t\t\tif (items.count === 0) {\n\t\t\t\tthrow new Error(`Product with id ${productId} not found`);\n\t\t\t}\n\n\t\t\tconst variantId = items.results[0].masterData.current.masterVariant.id;\n\t\t\tlineItem.variantId = variantId;\n\t\t\treturn lineItem;\n\t\t}\n\n\t\tthrow new Error(\n\t\t\t\"must provide either sku, productId or variantId for ShoppingListLineItem\",\n\t\t);\n\t};\n}\n","import type {\n\tChannelReference,\n\tChannelResourceIdentifier,\n\tDiscountedPriceDraft,\n\tStandalonePrice,\n\tStandalonePriceChangeActiveAction,\n\tStandalonePriceChangeValueAction,\n\tStandalonePriceDraft,\n\tStandalonePriceSetDiscountedPriceAction,\n\tStandalonePriceUpdateAction,\n} from \"@commercetools/platform-sdk\";\nimport type { Config } from \"#src/config.ts\";\nimport { getBaseResourceProperties } from \"../helpers.ts\";\nimport type { Writable } from \"../types.ts\";\nimport type { RepositoryContext, UpdateHandlerInterface } from \"./abstract.ts\";\nimport {\n\tAbstractResourceRepository,\n\tAbstractUpdateHandler,\n} from \"./abstract.ts\";\nimport { createTypedMoney } from \"./helpers.ts\";\n\nexport class StandAlonePriceRepository extends AbstractResourceRepository<\"standalone-price\"> {\n\tconstructor(config: Config) {\n\t\tsuper(\"standalone-price\", config);\n\t\tthis.actions = new StandalonePriceUpdateHandler(this._storage);\n\t}\n\n\tcreate(\n\t\tcontext: RepositoryContext,\n\t\tdraft: StandalonePriceDraft,\n\t): StandalonePrice {\n\t\tconst resource: StandalonePrice = {\n\t\t\t...getBaseResourceProperties(),\n\t\t\tactive: draft.active ? draft.active : false,\n\t\t\tsku: draft.sku,\n\t\t\tvalue: createTypedMoney(draft.value),\n\t\t\tcountry: draft.country,\n\t\t\tdiscounted: draft.discounted\n\t\t\t\t? transformDiscountDraft(draft.discounted)\n\t\t\t\t: undefined,\n\t\t\tchannel: draft.channel?.id\n\t\t\t\t? this.transformChannelReferenceDraft(draft.channel)\n\t\t\t\t: undefined,\n\t\t\tvalidFrom: draft.validFrom,\n\t\t\tvalidUntil: draft.validUntil,\n\t\t};\n\t\treturn this.saveNew(context, resource);\n\t}\n\n\ttransformChannelReferenceDraft(\n\t\tchannel: ChannelResourceIdentifier,\n\t): ChannelReference {\n\t\treturn {\n\t\t\ttypeId: channel.typeId,\n\t\t\tid: channel.id as string,\n\t\t};\n\t}\n}\n\nconst transformDiscountDraft = (discounted: DiscountedPriceDraft) => ({\n\tvalue: createTypedMoney(discounted.value),\n\tdiscount: discounted.discount,\n});\n\nclass StandalonePriceUpdateHandler\n\textends AbstractUpdateHandler\n\timplements\n\t\tPartial<\n\t\t\tUpdateHandlerInterface<StandalonePrice, StandalonePriceUpdateAction>\n\t\t>\n{\n\tchangeValue(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<StandalonePrice>,\n\t\taction: StandalonePriceChangeValueAction,\n\t) {\n\t\tresource.value = createTypedMoney(action.value);\n\t}\n\n\tsetActive(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<StandalonePrice>,\n\t\taction: StandalonePriceChangeActiveAction,\n\t) {\n\t\tresource.active = action.active;\n\t}\n\n\tsetDiscountedPrice(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<StandalonePrice>,\n\t\taction: StandalonePriceSetDiscountedPriceAction,\n\t) {\n\t\tresource.discounted = action.discounted\n\t\t\t? transformDiscountDraft(action.discounted)\n\t\t\t: undefined;\n\t}\n}\n","import type {\n\tState,\n\tStateAddRolesAction,\n\tStateChangeInitialAction,\n\tStateChangeKeyAction,\n\tStateChangeTypeAction,\n\tStateDraft,\n\tStateReference,\n\tStateRemoveRolesAction,\n\tStateSetDescriptionAction,\n\tStateSetNameAction,\n\tStateSetRolesAction,\n\tStateSetTransitionsAction,\n\tStateUpdateAction,\n} from \"@commercetools/platform-sdk\";\nimport type { Config } from \"#src/config.ts\";\nimport { getBaseResourceProperties } from \"../helpers.ts\";\nimport type { Writable } from \"../types.ts\";\nimport type { RepositoryContext, UpdateHandlerInterface } from \"./abstract.ts\";\nimport {\n\tAbstractResourceRepository,\n\tAbstractUpdateHandler,\n} from \"./abstract.ts\";\nimport { getReferenceFromResourceIdentifier } from \"./helpers.ts\";\n\nexport class StateRepository extends AbstractResourceRepository<\"state\"> {\n\tconstructor(config: Config) {\n\t\tsuper(\"state\", config);\n\t\tthis.actions = new StateUpdateHandler(config.storage);\n\t}\n\n\tcreate(context: RepositoryContext, draft: StateDraft): State {\n\t\tconst resource: State = {\n\t\t\t...getBaseResourceProperties(),\n\t\t\t...draft,\n\t\t\tbuiltIn: false,\n\t\t\tinitial: draft.initial || false,\n\t\t\ttransitions: (draft.transitions || []).map((t) =>\n\t\t\t\tgetReferenceFromResourceIdentifier(\n\t\t\t\t\tt,\n\t\t\t\t\tcontext.projectKey,\n\t\t\t\t\tthis._storage,\n\t\t\t\t),\n\t\t\t),\n\t\t};\n\n\t\treturn this.saveNew(context, resource);\n\t}\n}\n\nclass StateUpdateHandler\n\textends AbstractUpdateHandler\n\timplements UpdateHandlerInterface<State, StateUpdateAction>\n{\n\taddRoles(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<State>,\n\t\taction: StateAddRolesAction,\n\t) {\n\t\tif (!resource.roles) {\n\t\t\tresource.roles = [];\n\t\t}\n\t\tfor (const role of action.roles) {\n\t\t\tif (!resource.roles.includes(role)) {\n\t\t\t\tresource.roles.push(role);\n\t\t\t}\n\t\t}\n\t}\n\n\tchangeInitial(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<State>,\n\t\t{ initial }: StateChangeInitialAction,\n\t) {\n\t\tresource.initial = initial;\n\t}\n\n\tchangeKey(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<State>,\n\t\t{ key }: StateChangeKeyAction,\n\t) {\n\t\tresource.key = key;\n\t}\n\n\tchangeType(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<State>,\n\t\taction: StateChangeTypeAction,\n\t) {\n\t\tresource.type = action.type;\n\t}\n\n\tremoveRoles(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<State>,\n\t\taction: StateRemoveRolesAction,\n\t) {\n\t\tresource.roles = resource.roles?.filter(\n\t\t\t(role) => !action.roles.includes(role),\n\t\t);\n\t}\n\n\tsetDescription(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<State>,\n\t\t{ description }: StateSetDescriptionAction,\n\t) {\n\t\tresource.description = description;\n\t}\n\n\tsetName(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<State>,\n\t\t{ name }: StateSetNameAction,\n\t) {\n\t\tresource.name = name;\n\t}\n\n\tsetRoles(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<State>,\n\t\t{ roles }: StateSetRolesAction,\n\t) {\n\t\tresource.roles = roles;\n\t}\n\n\tsetTransitions(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<State>,\n\t\t{ transitions }: StateSetTransitionsAction,\n\t) {\n\t\tresource.transitions = transitions?.map(\n\t\t\t(resourceId): StateReference => ({\n\t\t\t\tid: resourceId.id || \"\",\n\t\t\t\ttypeId: \"state\",\n\t\t\t}),\n\t\t);\n\t}\n}\n","import type {\n\tChannelReference,\n\tChannelResourceIdentifier,\n\tStore,\n\tStoreDraft,\n\tStoreSetCountriesAction,\n\tStoreSetCustomFieldAction,\n\tStoreSetCustomTypeAction,\n\tStoreSetDistributionChannelsAction,\n\tStoreSetLanguagesAction,\n\tStoreSetNameAction,\n\tStoreUpdateAction,\n} from \"@commercetools/platform-sdk\";\nimport type { Config } from \"#src/config.ts\";\nimport { getBaseResourceProperties } from \"../helpers.ts\";\nimport type { AbstractStorage } from \"../storage/abstract.ts\";\nimport type { Writable } from \"../types.ts\";\nimport type { RepositoryContext, UpdateHandlerInterface } from \"./abstract.ts\";\nimport {\n\tAbstractResourceRepository,\n\tAbstractUpdateHandler,\n} from \"./abstract.ts\";\nimport {\n\tcreateCustomFields,\n\tgetReferenceFromResourceIdentifier,\n} from \"./helpers.ts\";\n\nexport class StoreRepository extends AbstractResourceRepository<\"store\"> {\n\tconstructor(config: Config) {\n\t\tsuper(\"store\", config);\n\t\tthis.actions = new StoreUpdateHandler(this._storage);\n\t}\n\n\tcreate(context: RepositoryContext, draft: StoreDraft): Store {\n\t\tconst resource: Store = {\n\t\t\t...getBaseResourceProperties(),\n\t\t\tkey: draft.key,\n\t\t\tname: draft.name,\n\t\t\tlanguages: draft.languages ?? [],\n\t\t\tcountries: draft.countries ?? [],\n\t\t\tdistributionChannels: transformChannels(\n\t\t\t\tcontext,\n\t\t\t\tthis._storage,\n\t\t\t\tdraft.distributionChannels,\n\t\t\t),\n\t\t\tsupplyChannels: transformChannels(\n\t\t\t\tcontext,\n\t\t\t\tthis._storage,\n\t\t\t\tdraft.supplyChannels,\n\t\t\t),\n\t\t\tproductSelections: [],\n\t\t\tcustom: createCustomFields(\n\t\t\t\tdraft.custom,\n\t\t\t\tcontext.projectKey,\n\t\t\t\tthis._storage,\n\t\t\t),\n\t\t};\n\t\treturn this.saveNew(context, resource);\n\t}\n}\n\nconst transformChannels = (\n\tcontext: RepositoryContext,\n\tstorage: AbstractStorage,\n\tchannels?: ChannelResourceIdentifier[],\n) => {\n\tif (!channels) return [];\n\n\treturn channels.map((ref) =>\n\t\tgetReferenceFromResourceIdentifier<ChannelReference>(\n\t\t\tref,\n\t\t\tcontext.projectKey,\n\t\t\tstorage,\n\t\t),\n\t);\n};\n\nclass StoreUpdateHandler\n\textends AbstractUpdateHandler\n\timplements Partial<UpdateHandlerInterface<Store, StoreUpdateAction>>\n{\n\tsetCountries(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Store>,\n\t\t{ countries }: StoreSetCountriesAction,\n\t) {\n\t\tresource.countries = countries ?? [];\n\t}\n\n\tsetCustomField(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Store>,\n\t\t{ name, value }: StoreSetCustomFieldAction,\n\t) {\n\t\tif (!resource.custom) {\n\t\t\treturn;\n\t\t}\n\t\tif (value === null) {\n\t\t\tdelete resource.custom.fields[name];\n\t\t} else {\n\t\t\tresource.custom.fields[name] = value;\n\t\t}\n\t}\n\n\tsetCustomType(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Store>,\n\t\t{ type, fields }: StoreSetCustomTypeAction,\n\t) {\n\t\tif (type) {\n\t\t\tresource.custom = createCustomFields(\n\t\t\t\t{ type, fields },\n\t\t\t\tcontext.projectKey,\n\t\t\t\tthis._storage,\n\t\t\t);\n\t\t} else {\n\t\t\tresource.custom = undefined;\n\t\t}\n\t}\n\n\tsetDistributionChannels(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Store>,\n\t\t{ distributionChannels }: StoreSetDistributionChannelsAction,\n\t) {\n\t\tresource.distributionChannels = transformChannels(\n\t\t\tcontext,\n\t\t\tthis._storage,\n\t\t\tdistributionChannels,\n\t\t);\n\t}\n\n\tsetLanguages(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Store>,\n\t\t{ languages }: StoreSetLanguagesAction,\n\t) {\n\t\tresource.languages = languages ?? [];\n\t}\n\n\tsetName(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Store>,\n\t\t{ name }: StoreSetNameAction,\n\t) {\n\t\tresource.name = name;\n\t}\n}\n","import type {\n\tInvalidInputError,\n\tSubscription,\n\tSubscriptionDraft,\n\tSubscriptionSetKeyAction,\n\tSubscriptionUpdateAction,\n} from \"@commercetools/platform-sdk\";\nimport type { Config } from \"#src/config.ts\";\nimport { CommercetoolsError } from \"#src/exceptions.ts\";\nimport { getBaseResourceProperties } from \"../helpers.ts\";\nimport type { Writable } from \"../types.ts\";\nimport type { RepositoryContext, UpdateHandlerInterface } from \"./abstract.ts\";\nimport {\n\tAbstractResourceRepository,\n\tAbstractUpdateHandler,\n} from \"./abstract.ts\";\n\nexport class SubscriptionRepository extends AbstractResourceRepository<\"subscription\"> {\n\tconstructor(config: Config) {\n\t\tsuper(\"subscription\", config);\n\t\tthis.actions = new SubscriptionUpdateHandler(config.storage);\n\t}\n\n\tcreate(context: RepositoryContext, draft: SubscriptionDraft): Subscription {\n\t\t// TODO: We could actually test this here by using the aws sdk. For now\n\t\t// hardcode a failed check when account id is 0000000000\n\t\tif (draft.destination.type === \"SQS\") {\n\t\t\tconst queueURL = new URL(draft.destination.queueUrl);\n\t\t\tconst accountId = queueURL.pathname.split(\"/\")[1];\n\t\t\tif (accountId === \"0000000000\") {\n\t\t\t\tconst dest = draft.destination;\n\t\t\t\tthrow new CommercetoolsError<InvalidInputError>(\n\t\t\t\t\t{\n\t\t\t\t\t\tcode: \"InvalidInput\",\n\t\t\t\t\t\tmessage: `A test message could not be delivered to this destination: SQS ${dest.queueUrl} in ${dest.region} for ${dest.accessKey}. Please make sure your destination is correctly configured.`,\n\t\t\t\t\t},\n\t\t\t\t\t400,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tconst resource: Subscription = {\n\t\t\t...getBaseResourceProperties(),\n\t\t\tchanges: draft.changes || [],\n\t\t\tdestination: draft.destination,\n\t\t\tformat: draft.format || {\n\t\t\t\ttype: \"Platform\",\n\t\t\t},\n\t\t\tkey: draft.key,\n\t\t\tmessages: draft.messages || [],\n\t\t\tstatus: \"Healthy\",\n\t\t\tevents: draft.events || [],\n\t\t};\n\t\treturn this.saveNew(context, resource);\n\t}\n}\n\nclass SubscriptionUpdateHandler\n\textends AbstractUpdateHandler\n\timplements\n\t\tPartial<UpdateHandlerInterface<Subscription, SubscriptionUpdateAction>>\n{\n\tsetKey(\n\t\t_context: RepositoryContext,\n\t\tresource: Writable<Subscription>,\n\t\t{ key }: SubscriptionSetKeyAction,\n\t) {\n\t\tresource.key = key;\n\t}\n}\n","import type { TaxRate, TaxRateDraft } from \"@commercetools/platform-sdk\";\nimport { v4 as uuidv4 } from \"uuid\";\n\nexport const taxRateFromTaxRateDraft = (draft: TaxRateDraft): TaxRate => ({\n\t...draft,\n\tid: uuidv4(),\n\tamount: draft.amount || 0,\n});\n","import type {\n\tTaxCategory,\n\tTaxCategoryAddTaxRateAction,\n\tTaxCategoryChangeNameAction,\n\tTaxCategoryRemoveTaxRateAction,\n\tTaxCategoryReplaceTaxRateAction,\n\tTaxCategorySetDescriptionAction,\n\tTaxCategorySetKeyAction,\n\tTaxCategoryUpdateAction,\n} from \"@commercetools/platform-sdk\";\nimport type { Writable } from \"#src/types.ts\";\nimport type { RepositoryContext } from \"../abstract.ts\";\nimport { AbstractUpdateHandler } from \"../abstract.ts\";\nimport { taxRateFromTaxRateDraft } from \"./helpers.ts\";\n\ntype TaxCategoryUpdateHandlerMethod<T> = (\n\tcontext: RepositoryContext,\n\tresource: Writable<TaxCategory>,\n\taction: T,\n) => void;\n\ntype TaxCategoryUpdateActions = {\n\t[P in TaxCategoryUpdateAction as P[\"action\"]]: TaxCategoryUpdateHandlerMethod<P>;\n};\n\nexport class TaxCategoryUpdateHandler\n\textends AbstractUpdateHandler\n\timplements TaxCategoryUpdateActions\n{\n\taddTaxRate(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<TaxCategory>,\n\t\t{ taxRate }: TaxCategoryAddTaxRateAction,\n\t) {\n\t\tif (resource.rates === undefined) {\n\t\t\tresource.rates = [];\n\t\t}\n\t\tresource.rates.push(taxRateFromTaxRateDraft(taxRate));\n\t}\n\n\tchangeName(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<TaxCategory>,\n\t\t{ name }: TaxCategoryChangeNameAction,\n\t) {\n\t\tresource.name = name;\n\t}\n\n\tremoveTaxRate(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<TaxCategory>,\n\t\t{ taxRateId }: TaxCategoryRemoveTaxRateAction,\n\t) {\n\t\tif (resource.rates === undefined) {\n\t\t\tresource.rates = [];\n\t\t}\n\t\tresource.rates = resource.rates.filter(\n\t\t\t(taxRate) => taxRate.id !== taxRateId,\n\t\t);\n\t}\n\n\treplaceTaxRate(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<TaxCategory>,\n\t\t{ taxRateId, taxRate }: TaxCategoryReplaceTaxRateAction,\n\t) {\n\t\tif (resource.rates === undefined) {\n\t\t\tresource.rates = [];\n\t\t}\n\n\t\tconst taxRateObj = taxRateFromTaxRateDraft(taxRate);\n\t\tfor (let i = 0; i < resource.rates.length; i++) {\n\t\t\tconst rate = resource.rates[i];\n\t\t\tif (rate.id === taxRateId) {\n\t\t\t\tresource.rates[i] = taxRateObj;\n\t\t\t}\n\t\t}\n\t}\n\n\tsetDescription(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<TaxCategory>,\n\t\t{ description }: TaxCategorySetDescriptionAction,\n\t) {\n\t\tresource.description = description;\n\t}\n\n\tsetKey(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<TaxCategory>,\n\t\t{ key }: TaxCategorySetKeyAction,\n\t) {\n\t\tresource.key = key;\n\t}\n}\n","import type {\n\tTaxCategory,\n\tTaxCategoryDraft,\n} from \"@commercetools/platform-sdk\";\nimport type { Config } from \"#src/config.ts\";\nimport { getBaseResourceProperties } from \"#src/helpers.ts\";\nimport type { RepositoryContext } from \"../abstract.ts\";\nimport { AbstractResourceRepository } from \"../abstract.ts\";\nimport { TaxCategoryUpdateHandler } from \"./actions.ts\";\nimport { taxRateFromTaxRateDraft } from \"./helpers.ts\";\n\nexport class TaxCategoryRepository extends AbstractResourceRepository<\"tax-category\"> {\n\tconstructor(config: Config) {\n\t\tsuper(\"tax-category\", config);\n\t\tthis.actions = new TaxCategoryUpdateHandler(this._storage);\n\t}\n\n\tcreate(context: RepositoryContext, draft: TaxCategoryDraft): TaxCategory {\n\t\tconst resource: TaxCategory = {\n\t\t\t...getBaseResourceProperties(),\n\t\t\t...draft,\n\t\t\trates: draft.rates?.map(taxRateFromTaxRateDraft) || [],\n\t\t};\n\t\treturn this.saveNew(context, resource);\n\t}\n}\n","import { isDeepStrictEqual } from \"node:util\";\nimport type {\n\tFieldDefinition,\n\tInvalidOperationError,\n\tType,\n\tTypeAddEnumValueAction,\n\tTypeAddFieldDefinitionAction,\n\tTypeChangeEnumValueLabelAction,\n\tTypeChangeFieldDefinitionOrderAction,\n\tTypeChangeNameAction,\n\tTypeRemoveFieldDefinitionAction,\n\tTypeSetDescriptionAction,\n\tTypeUpdateAction,\n} from \"@commercetools/platform-sdk\";\nimport { CommercetoolsError } from \"#src/exceptions.ts\";\nimport type { Writable } from \"#src/types.ts\";\nimport type { RepositoryContext } from \"../abstract.ts\";\nimport { AbstractUpdateHandler } from \"../abstract.ts\";\n\ntype TypeUpdateHandlerMethod<T> = (\n\tcontext: RepositoryContext,\n\tresource: Writable<Type>,\n\taction: T,\n) => void;\n\ntype TypeUpdateActions = Partial<{\n\t[P in TypeUpdateAction as P[\"action\"]]: TypeUpdateHandlerMethod<P>;\n}>;\n\nexport class TypeUpdateHandler\n\textends AbstractUpdateHandler\n\timplements TypeUpdateActions\n{\n\taddEnumValue(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Type>,\n\t\t{ fieldName, value }: TypeAddEnumValueAction,\n\t) {\n\t\tresource.fieldDefinitions.forEach((field) => {\n\t\t\tif (field.name === fieldName) {\n\t\t\t\t// TODO, should be done better i suppose\n\t\t\t\tif (field.type.name === \"Enum\") {\n\t\t\t\t\tfield.type.values.push(value);\n\t\t\t\t} else if (\n\t\t\t\t\tfield.type.name === \"Set\" &&\n\t\t\t\t\tfield.type.elementType.name === \"Enum\"\n\t\t\t\t) {\n\t\t\t\t\tfield.type.elementType.values.push(value);\n\t\t\t\t} else {\n\t\t\t\t\tthrow new Error(\"Type is not a Enum (or Set of Enum)\");\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t}\n\n\taddFieldDefinition(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Type>,\n\t\t{ fieldDefinition }: TypeAddFieldDefinitionAction,\n\t) {\n\t\tresource.fieldDefinitions.push(fieldDefinition);\n\t}\n\n\tchangeEnumValueLabel(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Type>,\n\t\t{ fieldName, value }: TypeChangeEnumValueLabelAction,\n\t) {\n\t\tresource.fieldDefinitions.forEach((field) => {\n\t\t\tif (field.name === fieldName) {\n\t\t\t\t// TODO, should be done better i suppose\n\t\t\t\tif (field.type.name === \"Enum\") {\n\t\t\t\t\tfield.type.values.forEach((v) => {\n\t\t\t\t\t\tif (v.key === value.key) {\n\t\t\t\t\t\t\tv.label = value.label;\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t} else if (\n\t\t\t\t\tfield.type.name === \"Set\" &&\n\t\t\t\t\tfield.type.elementType.name === \"Enum\"\n\t\t\t\t) {\n\t\t\t\t\tfield.type.elementType.values.forEach((v) => {\n\t\t\t\t\t\tif (v.key === value.key) {\n\t\t\t\t\t\t\tv.label = value.label;\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\tthrow new Error(\"Type is not a Enum (or Set of Enum)\");\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t}\n\n\tchangeFieldDefinitionOrder(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Type>,\n\t\t{ fieldNames }: TypeChangeFieldDefinitionOrderAction,\n\t) {\n\t\tconst fields = new Map(\n\t\t\tresource.fieldDefinitions.map((item) => [item.name, item]),\n\t\t);\n\t\tconst result: FieldDefinition[] = [];\n\t\tlet current = resource.fieldDefinitions;\n\n\t\tfieldNames.forEach((fieldName) => {\n\t\t\tconst field = fields.get(fieldName);\n\t\t\tif (field === undefined) {\n\t\t\t\tthrow new Error(\"New field\");\n\t\t\t}\n\t\t\tresult.push(field);\n\n\t\t\t// Remove from current items\n\t\t\tcurrent = current.filter((f) => f.name !== fieldName);\n\t\t});\n\n\t\tif (\n\t\t\tisDeepStrictEqual(\n\t\t\t\tfieldNames,\n\t\t\t\tresource.fieldDefinitions.map((item) => item.name),\n\t\t\t)\n\t\t) {\n\t\t\tthrow new CommercetoolsError<InvalidOperationError>({\n\t\t\t\tcode: \"InvalidOperation\",\n\t\t\t\tmessage: \"'fieldDefinitions' has no changes.\",\n\t\t\t\taction: {\n\t\t\t\t\taction: \"changeFieldDefinitionOrder\",\n\t\t\t\t\tfieldNames: fieldNames,\n\t\t\t\t},\n\t\t\t});\n\t\t}\n\n\t\tresource.fieldDefinitions = result;\n\t\t// Add fields which were not specified in the order as last items. Not\n\t\t// sure if this follows commercetools\n\t\tresource.fieldDefinitions.push(...current);\n\t}\n\n\tchangeName(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Type>,\n\t\t{ name }: TypeChangeNameAction,\n\t) {\n\t\tresource.name = name;\n\t}\n\n\tremoveFieldDefinition(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Type>,\n\t\t{ fieldName }: TypeRemoveFieldDefinitionAction,\n\t) {\n\t\tresource.fieldDefinitions = resource.fieldDefinitions.filter(\n\t\t\t(f) => f.name !== fieldName,\n\t\t);\n\t}\n\n\tsetDescription(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Type>,\n\t\t{ description }: TypeSetDescriptionAction,\n\t) {\n\t\tresource.description = description;\n\t}\n}\n","import type { Type, TypeDraft } from \"@commercetools/platform-sdk\";\nimport type { Config } from \"#src/config.ts\";\nimport { getBaseResourceProperties } from \"#src/helpers.ts\";\nimport type { RepositoryContext } from \"../abstract.ts\";\nimport { AbstractResourceRepository } from \"../abstract.ts\";\nimport { TypeUpdateHandler } from \"./actions.ts\";\n\nexport class TypeRepository extends AbstractResourceRepository<\"type\"> {\n\tconstructor(config: Config) {\n\t\tsuper(\"type\", config);\n\t\tthis.actions = new TypeUpdateHandler(config.storage);\n\t}\n\n\tcreate(context: RepositoryContext, draft: TypeDraft): Type {\n\t\tconst resource: Type = {\n\t\t\t...getBaseResourceProperties(),\n\t\t\tkey: draft.key,\n\t\t\tname: draft.name,\n\t\t\tresourceTypeIds: draft.resourceTypeIds,\n\t\t\tfieldDefinitions: draft.fieldDefinitions || [],\n\t\t\tdescription: draft.description,\n\t\t};\n\t\treturn this.saveNew(context, resource);\n\t}\n}\n","import type {\n\tZone,\n\tZoneAddLocationAction,\n\tZoneChangeNameAction,\n\tZoneDraft,\n\tZoneRemoveLocationAction,\n\tZoneSetDescriptionAction,\n\tZoneSetKeyAction,\n\tZoneUpdateAction,\n} from \"@commercetools/platform-sdk\";\nimport type { Config } from \"#src/config.ts\";\nimport { getBaseResourceProperties } from \"../helpers.ts\";\nimport type { Writable } from \"../types.ts\";\nimport type { RepositoryContext, UpdateHandlerInterface } from \"./abstract.ts\";\nimport {\n\tAbstractResourceRepository,\n\tAbstractUpdateHandler,\n} from \"./abstract.ts\";\n\nexport class ZoneRepository extends AbstractResourceRepository<\"zone\"> {\n\tconstructor(config: Config) {\n\t\tsuper(\"zone\", config);\n\t\tthis.actions = new ZoneUpdateHandler(config.storage);\n\t}\n\n\tcreate(context: RepositoryContext, draft: ZoneDraft): Zone {\n\t\tconst resource: Zone = {\n\t\t\t...getBaseResourceProperties(),\n\t\t\tkey: draft.key,\n\t\t\tlocations: draft.locations || [],\n\t\t\tname: draft.name,\n\t\t\tdescription: draft.description,\n\t\t};\n\t\treturn this.saveNew(context, resource);\n\t}\n}\n\nclass ZoneUpdateHandler\n\textends AbstractUpdateHandler\n\timplements Partial<UpdateHandlerInterface<Zone, ZoneUpdateAction>>\n{\n\taddLocation(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Zone>,\n\t\t{ location }: ZoneAddLocationAction,\n\t) {\n\t\tresource.locations.push(location);\n\t}\n\n\tchangeName(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Zone>,\n\t\t{ name }: ZoneChangeNameAction,\n\t) {\n\t\tresource.name = name;\n\t}\n\n\tremoveLocation(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Zone>,\n\t\t{ location }: ZoneRemoveLocationAction,\n\t) {\n\t\tresource.locations = resource.locations.filter(\n\t\t\t(loc) =>\n\t\t\t\t!(loc.country === location.country && loc.state === location.state),\n\t\t);\n\t}\n\n\tsetDescription(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Zone>,\n\t\t{ description }: ZoneSetDescriptionAction,\n\t) {\n\t\tresource.description = description;\n\t}\n\n\tsetKey(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Zone>,\n\t\t{ key }: ZoneSetKeyAction,\n\t) {\n\t\tresource.key = key;\n\t}\n}\n","import type { Config } from \"#src/config.ts\";\nimport { ProductTailoringRepository } from \"#src/repositories/product-tailoring.ts\";\nimport {\n\tAsAssociateCartRepository,\n\tAsAssociateOrderRepository,\n\tAsAssociateQuoteRequestRepository,\n} from \"./as-associate.ts\";\nimport { AssociateRoleRepository } from \"./associate-role.ts\";\nimport { AttributeGroupRepository } from \"./attribute-group.ts\";\nimport { BusinessUnitRepository } from \"./business-unit.ts\";\nimport { CartRepository } from \"./cart/index.ts\";\nimport { CartDiscountRepository } from \"./cart-discount/index.ts\";\nimport { CategoryRepository } from \"./category/index.ts\";\nimport { ChannelRepository } from \"./channel.ts\";\nimport { CustomObjectRepository } from \"./custom-object.ts\";\nimport { CustomerRepository } from \"./customer/index.ts\";\nimport { CustomerGroupRepository } from \"./customer-group.ts\";\nimport { DiscountCodeRepository } from \"./discount-code/index.ts\";\nimport { DiscountGroupRepository } from \"./discount-group/index.ts\";\nimport { ExtensionRepository } from \"./extension.ts\";\nimport { InventoryEntryRepository } from \"./inventory-entry/index.ts\";\nimport { MyCustomerRepository } from \"./my-customer.ts\";\nimport { MyOrderRepository } from \"./my-order.ts\";\nimport { OrderRepository } from \"./order/index.ts\";\nimport { OrderEditRepository } from \"./order-edit.ts\";\nimport { PaymentRepository } from \"./payment/index.ts\";\nimport { ProductRepository } from \"./product/index.ts\";\nimport { ProductDiscountRepository } from \"./product-discount.ts\";\nimport { ProductProjectionRepository } from \"./product-projection.ts\";\nimport { ProductSelectionRepository } from \"./product-selection.ts\";\nimport { ProductTypeRepository } from \"./product-type.ts\";\nimport { ProjectRepository } from \"./project.ts\";\nimport { QuoteRepository } from \"./quote/index.ts\";\nimport { QuoteRequestRepository } from \"./quote-request/index.ts\";\nimport { StagedQuoteRepository } from \"./quote-staged/index.ts\";\nimport { RecurrencePolicyRepository } from \"./recurrence-policy/index.ts\";\nimport { RecurringOrderRepository } from \"./recurring-order/index.ts\";\nimport { ReviewRepository } from \"./review.ts\";\nimport { ShippingMethodRepository } from \"./shipping-method/index.ts\";\nimport { ShoppingListRepository } from \"./shopping-list/index.ts\";\nimport { StandAlonePriceRepository } from \"./standalone-price.ts\";\nimport { StateRepository } from \"./state.ts\";\nimport { StoreRepository } from \"./store.ts\";\nimport { SubscriptionRepository } from \"./subscription.ts\";\nimport { TaxCategoryRepository } from \"./tax-category/index.ts\";\nimport { TypeRepository } from \"./type/index.ts\";\nimport { ZoneRepository } from \"./zone.ts\";\n\nexport type RepositoryMap = ReturnType<typeof createRepositories>;\n\nexport const createRepositories = (config: Config) => ({\n\t\"as-associate\": {\n\t\tcart: new AsAssociateCartRepository(config),\n\t\torder: new AsAssociateOrderRepository(config),\n\t\t\"quote-request\": new AsAssociateQuoteRequestRepository(config),\n\t},\n\t\"associate-role\": new AssociateRoleRepository(config),\n\t\"attribute-group\": new AttributeGroupRepository(config),\n\t\"business-unit\": new BusinessUnitRepository(config),\n\tcategory: new CategoryRepository(config),\n\tcart: new CartRepository(config),\n\t\"cart-discount\": new CartDiscountRepository(config),\n\tcustomer: new CustomerRepository(config),\n\tchannel: new ChannelRepository(config),\n\t\"customer-group\": new CustomerGroupRepository(config),\n\t\"discount-code\": new DiscountCodeRepository(config),\n\t\"discount-group\": new DiscountGroupRepository(config),\n\textension: new ExtensionRepository(config),\n\t\"inventory-entry\": new InventoryEntryRepository(config),\n\t\"key-value-document\": new CustomObjectRepository(config),\n\torder: new OrderRepository(config),\n\t\"order-edit\": new OrderEditRepository(config),\n\tpayment: new PaymentRepository(config),\n\t\"my-cart\": new CartRepository(config),\n\t\"my-order\": new MyOrderRepository(config),\n\t\"my-customer\": new MyCustomerRepository(config),\n\t\"my-payment\": new PaymentRepository(config),\n\t\"my-shopping-list\": new ShoppingListRepository(config),\n\tproduct: new ProductRepository(config),\n\t\"product-type\": new ProductTypeRepository(config),\n\t\"product-discount\": new ProductDiscountRepository(config),\n\t\"product-projection\": new ProductProjectionRepository(config),\n\t\"product-selection\": new ProductSelectionRepository(config),\n\t\"product-tailoring\": new ProductTailoringRepository(config),\n\tproject: new ProjectRepository(config),\n\t\"recurring-order\": new RecurringOrderRepository(config),\n\t\"recurrence-policy\": new RecurrencePolicyRepository(config),\n\treview: new ReviewRepository(config),\n\tquote: new QuoteRepository(config),\n\t\"quote-request\": new QuoteRequestRepository(config),\n\t\"shipping-method\": new ShippingMethodRepository(config),\n\t\"shopping-list\": new ShoppingListRepository(config),\n\t\"staged-quote\": new StagedQuoteRepository(config),\n\t\"standalone-price\": new StandAlonePriceRepository(config),\n\tstate: new StateRepository(config),\n\tstore: new StoreRepository(config),\n\tsubscription: new SubscriptionRepository(config),\n\t\"tax-category\": new TaxCategoryRepository(config),\n\ttype: new TypeRepository(config),\n\tzone: new ZoneRepository(config),\n});\n","import { z } from \"zod\";\n\nconst UpdateActionSchema = z\n\t.object({\n\t\taction: z.string(),\n\t})\n\t.passthrough();\n\nexport const updateRequestSchema = z.object({\n\tversion: z.number(),\n\tactions: z.array(UpdateActionSchema),\n});\n","import type { InvalidJsonInputError } from \"@commercetools/platform-sdk\";\nimport type { z } from \"zod\";\nimport { fromZodError } from \"zod-validation-error\";\nimport { CommercetoolsError } from \"./exceptions.ts\";\n\nexport const validateData = <T>(data: any, schema: z.AnyZodObject) => {\n\ttry {\n\t\tschema.parse(data);\n\t\treturn data as T;\n\t} catch (err: any) {\n\t\tconst validationError = fromZodError(err);\n\t\tthrow new CommercetoolsError<InvalidJsonInputError>({\n\t\t\tcode: \"InvalidJsonInput\",\n\t\t\tmessage: \"Request body does not contain valid JSON.\",\n\t\t\tdetailedErrorMessage: validationError.toString(),\n\t\t});\n\t}\n};\n","import type { Update } from \"@commercetools/platform-sdk\";\nimport { type Request, type Response, Router } from \"express\";\nimport type { ParsedQs } from \"qs\";\nimport { updateRequestSchema } from \"#src/schemas/update-request.ts\";\nimport { validateData } from \"#src/validate.ts\";\nimport { queryParamsArray } from \"../helpers.ts\";\nimport type {\n\tAbstractResourceRepository,\n\tQueryParams,\n} from \"../repositories/abstract.ts\";\nimport { getRepositoryContext } from \"../repositories/helpers.ts\";\n\nexport default abstract class AbstractService {\n\tpublic abstract repository: AbstractResourceRepository<any>;\n\n\tcreateStatusCode = 201;\n\n\tconstructor(parent: Router) {\n\t\tthis.registerRoutes(parent);\n\t}\n\n\tprotected abstract getBasePath(): string;\n\n\textraRoutes(router: Router) {}\n\n\tregisterRoutes(parent: Router) {\n\t\tconst basePath = this.getBasePath();\n\t\tconst router = Router({ mergeParams: true });\n\n\t\t// Bind this first since the `/:id` routes are currently a bit to greedy\n\t\tthis.extraRoutes(router);\n\n\t\trouter.get(\"/\", this.get.bind(this));\n\t\trouter.get(\"/key=:key\", this.getWithKey.bind(this)); // same thing goes for the key routes\n\t\trouter.get(\"/:id\", this.getWithId.bind(this));\n\n\t\trouter.delete(\"/key=:key\", this.deleteWithKey.bind(this));\n\t\trouter.delete(\"/:id\", this.deleteWithId.bind(this));\n\n\t\trouter.post(\"/\", this.post.bind(this));\n\t\trouter.post(\"/key=:key\", this.postWithKey.bind(this));\n\t\trouter.post(\"/:id\", this.postWithId.bind(this));\n\n\t\tparent.use(`/${basePath}`, router);\n\t}\n\n\tget(request: Request, response: Response) {\n\t\tconst limit = this._parseParam(request.query.limit);\n\t\tconst offset = this._parseParam(request.query.offset);\n\t\tconst params: QueryParams = {\n\t\t\texpand: this._parseParam(request.query.expand),\n\t\t\twhere: this._parseParam(request.query.where),\n\t\t\tlimit: limit !== undefined ? Number(limit) : undefined,\n\t\t\toffset: offset !== undefined ? Number(offset) : undefined,\n\t\t};\n\n\t\tfor (const key in request.query) {\n\t\t\tif (key.startsWith(\"var.\")) {\n\t\t\t\tconst items = this._parseParam(request.query[key]);\n\t\t\t\tif (items) {\n\t\t\t\t\tparams[key] = items.length === 1 ? items[0] : items;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tconst result = this.repository.query(getRepositoryContext(request), params);\n\t\tresponse.status(200).send(result);\n\t\treturn;\n\t}\n\n\tgetWithId(request: Request, response: Response) {\n\t\tconst result = this._expandWithId(request, request.params.id);\n\t\tif (!result) {\n\t\t\tresponse.status(404).send({\n\t\t\t\tstatusCode: 404,\n\t\t\t\tmessage: `The Resource with ID '${request.params.id} was not found.`,\n\t\t\t\terrors: [\n\t\t\t\t\t{\n\t\t\t\t\t\tcode: \"ResourceNotFound\",\n\t\t\t\t\t\tmessage: `The Resource with ID '${request.params.id} was not found.`,\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\t\tresponse.status(200).send(result);\n\t}\n\n\tgetWithKey(request: Request, response: Response) {\n\t\tconst result = this.repository.getByKey(\n\t\t\tgetRepositoryContext(request),\n\t\t\trequest.params.key,\n\t\t\t{\n\t\t\t\texpand: this._parseParam(request.query.expand),\n\t\t\t},\n\t\t);\n\t\tif (!result) {\n\t\t\tresponse.status(404).send({\n\t\t\t\tstatusCode: 404,\n\t\t\t\tmessage: `The Resource with key '${request.params.id} was not found.`,\n\t\t\t\terrors: [\n\t\t\t\t\t{\n\t\t\t\t\t\tcode: \"ResourceNotFound\",\n\t\t\t\t\t\tmessage: `The Resource with key '${request.params.id} was not found.`,\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\t\tresponse.status(200).send(result);\n\t}\n\n\tdeleteWithId(request: Request, response: Response) {\n\t\tconst result = this.repository.delete(\n\t\t\tgetRepositoryContext(request),\n\t\t\trequest.params.id,\n\t\t\t{\n\t\t\t\texpand: this._parseParam(request.query.expand),\n\t\t\t},\n\t\t);\n\t\tif (!result) {\n\t\t\tresponse.status(404).send({ statusCode: 404 });\n\t\t\treturn;\n\t\t}\n\t\tresponse.status(200).send(result);\n\t}\n\n\tdeleteWithKey(request: Request, response: Response) {\n\t\tconst resource = this.repository.getByKey(\n\t\t\tgetRepositoryContext(request),\n\t\t\trequest.params.key,\n\t\t);\n\t\tif (!resource) {\n\t\t\tresponse.status(404).send({ statusCode: 404 });\n\t\t\treturn;\n\t\t}\n\n\t\tconst result = this.repository.delete(\n\t\t\tgetRepositoryContext(request),\n\t\t\tresource.id,\n\t\t\t{\n\t\t\t\texpand: this._parseParam(request.query.expand),\n\t\t\t},\n\t\t);\n\t\tif (!result) {\n\t\t\tresponse.status(404).send({ statusCode: 404 });\n\t\t\treturn;\n\t\t}\n\t\tresponse.status(200).send(result);\n\t}\n\n\tpost(request: Request, response: Response) {\n\t\tconst draft = request.body;\n\t\tconst resource = this.repository.create(\n\t\t\tgetRepositoryContext(request),\n\t\t\tdraft,\n\t\t);\n\t\tconst result = this._expandWithId(request, resource.id);\n\t\tresponse.status(this.createStatusCode).send(result);\n\t}\n\n\tpostWithId(request: Request, response: Response) {\n\t\tconst updateRequest = validateData<Update>(\n\t\t\trequest.body,\n\t\t\tupdateRequestSchema,\n\t\t);\n\t\tconst resource = this.repository.get(\n\t\t\tgetRepositoryContext(request),\n\t\t\trequest.params.id,\n\t\t);\n\t\tif (!resource) {\n\t\t\tresponse.status(404).send({ statusCode: 404 });\n\t\t\treturn;\n\t\t}\n\n\t\tconst updatedResource = this.repository.processUpdateActions(\n\t\t\tgetRepositoryContext(request),\n\t\t\tresource,\n\t\t\tupdateRequest.version,\n\t\t\tupdateRequest.actions,\n\t\t);\n\n\t\tconst result = this._expandWithId(request, updatedResource.id);\n\t\tresponse.status(200).send(result);\n\t}\n\n\tpostWithKey(request: Request, response: Response) {\n\t\tconst updateRequest = validateData<Update>(\n\t\t\trequest.body,\n\t\t\tupdateRequestSchema,\n\t\t);\n\n\t\tconst resource = this.repository.getByKey(\n\t\t\tgetRepositoryContext(request),\n\t\t\trequest.params.key,\n\t\t);\n\t\tif (!resource) {\n\t\t\tresponse.status(404).send({ statusCode: 404 });\n\t\t\treturn;\n\t\t}\n\n\t\tconst updatedResource = this.repository.processUpdateActions(\n\t\t\tgetRepositoryContext(request),\n\t\t\tresource,\n\t\t\tupdateRequest.version,\n\t\t\tupdateRequest.actions,\n\t\t);\n\n\t\tconst result = this._expandWithId(request, updatedResource.id);\n\t\tresponse.status(200).send(result);\n\t}\n\n\tprotected _expandWithId(request: Request, resourceId: string) {\n\t\tconst result = this.repository.get(\n\t\t\tgetRepositoryContext(request),\n\t\t\tresourceId,\n\t\t\t{\n\t\t\t\texpand: this._parseParam(request.query.expand),\n\t\t\t},\n\t\t);\n\t\treturn result;\n\t}\n\n\t// No idea what i'm doing\n\tprotected _parseParam(\n\t\tvalue: string | ParsedQs | string[] | ParsedQs[] | undefined,\n\t): string[] | undefined {\n\t\treturn queryParamsArray(value);\n\t}\n}\n","import { Router } from \"express\";\nimport type { CartRepository } from \"../repositories/cart/index.ts\";\nimport AbstractService from \"./abstract.ts\";\n\nexport class AsAssociateCartService extends AbstractService {\n\tpublic repository: CartRepository;\n\n\tconstructor(parent: Router, repository: CartRepository) {\n\t\tsuper(parent);\n\t\tthis.repository = repository;\n\t}\n\n\tgetBasePath() {\n\t\treturn \"carts\";\n\t}\n\n\tregisterRoutes(parent: Router) {\n\t\tconst basePath = this.getBasePath();\n\t\tconst router = Router({ mergeParams: true });\n\n\t\tthis.extraRoutes(router);\n\n\t\trouter.get(\"/\", this.get.bind(this));\n\t\trouter.get(\"/:id\", this.getWithId.bind(this));\n\n\t\trouter.delete(\"/:id\", this.deleteWithId.bind(this));\n\n\t\trouter.post(\"/\", this.post.bind(this));\n\t\trouter.post(\"/:id\", this.postWithId.bind(this));\n\n\t\tparent.use(`/${basePath}`, router);\n\t}\n}\n","import { Router } from \"express\";\nimport type { MyOrderRepository } from \"../repositories/my-order.ts\";\nimport AbstractService from \"./abstract.ts\";\n\nexport class AsAssociateOrderService extends AbstractService {\n\tpublic repository: MyOrderRepository;\n\n\tconstructor(parent: Router, repository: MyOrderRepository) {\n\t\tsuper(parent);\n\t\tthis.repository = repository;\n\t}\n\n\tgetBasePath() {\n\t\treturn \"orders\";\n\t}\n\n\tregisterRoutes(parent: Router) {\n\t\tconst basePath = this.getBasePath();\n\t\tconst router = Router({ mergeParams: true });\n\n\t\tthis.extraRoutes(router);\n\n\t\trouter.get(\"/\", this.get.bind(this));\n\t\trouter.get(\"/:id\", this.getWithId.bind(this));\n\n\t\trouter.delete(\"/:id\", this.deleteWithId.bind(this));\n\n\t\trouter.post(\"/\", this.post.bind(this));\n\t\trouter.post(\"/:id\", this.postWithId.bind(this));\n\n\t\tparent.use(`/${basePath}`, router);\n\t}\n}\n","import { Router } from \"express\";\nimport type { MyQuoteRequestRepository } from \"#src/repositories/my-quote-request.ts\";\nimport AbstractService from \"./abstract.ts\";\n\nexport class AsAssociateQuoteRequestService extends AbstractService {\n\tpublic repository: MyQuoteRequestRepository;\n\n\tconstructor(parent: Router, repository: MyQuoteRequestRepository) {\n\t\tsuper(parent);\n\t\tthis.repository = repository;\n\t}\n\n\tgetBasePath() {\n\t\treturn \"quote-requests\";\n\t}\n\n\tregisterRoutes(parent: Router) {\n\t\tconst basePath = this.getBasePath();\n\t\tconst router = Router({ mergeParams: true });\n\n\t\tthis.extraRoutes(router);\n\n\t\trouter.get(\"/\", this.get.bind(this));\n\t\trouter.get(\"/:id\", this.getWithId.bind(this));\n\n\t\trouter.delete(\"/:id\", this.deleteWithId.bind(this));\n\n\t\trouter.post(\"/\", this.post.bind(this));\n\t\trouter.post(\"/:id\", this.postWithId.bind(this));\n\n\t\tparent.use(`/${basePath}`, router);\n\t}\n}\n","import { Router } from \"express\";\nimport type {\n\tAsAssociateCartRepository,\n\tAsAssociateOrderRepository,\n\tAsAssociateQuoteRequestRepository,\n} from \"#src/repositories/as-associate.ts\";\nimport { AsAssociateCartService } from \"./as-associate-cart.ts\";\nimport { AsAssociateOrderService } from \"./as-associate-order.ts\";\nimport { AsAssociateQuoteRequestService } from \"./as-associate-quote-request.ts\";\n\ntype Repositories = {\n\tcart: AsAssociateCartRepository;\n\torder: AsAssociateOrderRepository;\n\t\"quote-request\": AsAssociateQuoteRequestRepository;\n};\n\nexport class AsAssociateService {\n\trouter: Router;\n\n\tsubServices: {\n\t\tcart: AsAssociateCartService;\n\t\torder: AsAssociateOrderService;\n\t\t\"quote-request\": AsAssociateQuoteRequestService;\n\t};\n\n\tconstructor(parent: Router, repositories: Repositories) {\n\t\tthis.router = Router({ mergeParams: true });\n\n\t\tthis.subServices = {\n\t\t\torder: new AsAssociateOrderService(this.router, repositories.order),\n\t\t\tcart: new AsAssociateCartService(this.router, repositories.cart),\n\t\t\t\"quote-request\": new AsAssociateQuoteRequestService(\n\t\t\t\tthis.router,\n\t\t\t\trepositories[\"quote-request\"],\n\t\t\t),\n\t\t};\n\t\tparent.use(\n\t\t\t\"/as-associate/:associateId/in-business-unit/key=:businessUnitId\",\n\t\t\tthis.router,\n\t\t);\n\t}\n}\n","import type { Router } from \"express\";\nimport type { AssociateRoleRepository } from \"../repositories/associate-role.ts\";\nimport AbstractService from \"./abstract.ts\";\n\nexport class AssociateRoleServices extends AbstractService {\n\tpublic repository: AssociateRoleRepository;\n\n\tconstructor(parent: Router, repository: AssociateRoleRepository) {\n\t\tsuper(parent);\n\n\t\tthis.repository = repository;\n\t}\n\n\tprotected getBasePath(): string {\n\t\treturn \"associate-roles\";\n\t}\n}\n","import type { Router } from \"express\";\nimport type { AttributeGroupRepository } from \"../repositories/attribute-group.ts\";\nimport AbstractService from \"./abstract.ts\";\n\nexport class AttributeGroupService extends AbstractService {\n\tpublic repository: AttributeGroupRepository;\n\n\tconstructor(parent: Router, repository: AttributeGroupRepository) {\n\t\tsuper(parent);\n\t\tthis.repository = repository;\n\t}\n\n\tgetBasePath() {\n\t\treturn \"attribute-groups\";\n\t}\n}\n","import type { Router } from \"express\";\nimport type { BusinessUnitRepository } from \"../repositories/business-unit.ts\";\nimport AbstractService from \"./abstract.ts\";\n\nexport class BusinessUnitServices extends AbstractService {\n\tpublic repository: BusinessUnitRepository;\n\n\tconstructor(parent: Router, repository: BusinessUnitRepository) {\n\t\tsuper(parent);\n\n\t\tthis.repository = repository;\n\t}\n\n\tprotected getBasePath(): string {\n\t\treturn \"business-units\";\n\t}\n}\n","import type { Cart, CartDraft, Order } from \"@commercetools/platform-sdk\";\nimport type { Request, Response, Router } from \"express\";\nimport type { CartRepository } from \"../repositories/cart/index.ts\";\nimport { getRepositoryContext } from \"../repositories/helpers.ts\";\nimport type { OrderRepository } from \"../repositories/order/index.ts\";\nimport AbstractService from \"./abstract.ts\";\n\nexport class CartService extends AbstractService {\n\tpublic repository: CartRepository;\n\n\tpublic orderRepository: OrderRepository;\n\n\tconstructor(\n\t\tparent: Router,\n\t\tcartRepository: CartRepository,\n\t\torderRepository: OrderRepository,\n\t) {\n\t\tsuper(parent);\n\t\tthis.repository = cartRepository;\n\t\tthis.orderRepository = orderRepository;\n\t}\n\n\tgetBasePath() {\n\t\treturn \"carts\";\n\t}\n\n\textraRoutes(parent: Router) {\n\t\tparent.post(\"/replicate\", this.replicate.bind(this));\n\t}\n\n\treplicate(request: Request, response: Response) {\n\t\tconst context = getRepositoryContext(request);\n\n\t\tconst cartOrOrder: Cart | Order | null =\n\t\t\trequest.body.reference.typeId === \"order\"\n\t\t\t\t? this.orderRepository.get(context, request.body.reference.id)\n\t\t\t\t: this.repository.get(context, request.body.reference.id);\n\n\t\tif (!cartOrOrder) {\n\t\t\tresponse.status(400).send();\n\t\t\treturn;\n\t\t}\n\n\t\tconst cartDraft: CartDraft = {\n\t\t\t...cartOrOrder,\n\t\t\tcurrency: cartOrOrder.totalPrice.currencyCode,\n\t\t\tdiscountCodes: [],\n\t\t\tshipping: [], // TODO: cartOrOrder.shipping,\n\t\t\tlineItems: cartOrOrder.lineItems.map((lineItem) => ({\n\t\t\t\t...lineItem,\n\t\t\t\tvariantId: lineItem.variant.id,\n\t\t\t\tsku: lineItem.variant.sku,\n\t\t\t})),\n\t\t};\n\n\t\tconst newCart = this.repository.create(context, cartDraft);\n\n\t\tresponse.status(200).send(newCart);\n\t}\n}\n","import type { Router } from \"express\";\nimport type { CartDiscountRepository } from \"../repositories/cart-discount/index.ts\";\nimport AbstractService from \"./abstract.ts\";\n\nexport class CartDiscountService extends AbstractService {\n\tpublic repository: CartDiscountRepository;\n\n\tconstructor(parent: Router, repository: CartDiscountRepository) {\n\t\tsuper(parent);\n\t\tthis.repository = repository;\n\t}\n\n\tgetBasePath() {\n\t\treturn \"cart-discounts\";\n\t}\n}\n","import type { Router } from \"express\";\nimport type { CategoryRepository } from \"../repositories/category/index.ts\";\nimport AbstractService from \"./abstract.ts\";\n\nexport class CategoryServices extends AbstractService {\n\tpublic repository: CategoryRepository;\n\n\tconstructor(parent: Router, repository: CategoryRepository) {\n\t\tsuper(parent);\n\t\tthis.repository = repository;\n\t}\n\n\tgetBasePath() {\n\t\treturn \"categories\";\n\t}\n}\n","import type { Router } from \"express\";\nimport type { ChannelRepository } from \"../repositories/channel.ts\";\nimport AbstractService from \"./abstract.ts\";\n\nexport class ChannelService extends AbstractService {\n\tpublic repository: ChannelRepository;\n\n\tconstructor(parent: Router, repository: ChannelRepository) {\n\t\tsuper(parent);\n\t\tthis.repository = repository;\n\t}\n\n\tgetBasePath() {\n\t\treturn \"channels\";\n\t}\n}\n","import type { CustomObjectDraft } from \"@commercetools/platform-sdk\";\nimport type { Request, Response, Router } from \"express\";\nimport type { CustomObjectRepository } from \"../repositories/custom-object.ts\";\nimport { getRepositoryContext } from \"../repositories/helpers.ts\";\nimport AbstractService from \"./abstract.ts\";\n\nexport class CustomObjectService extends AbstractService {\n\tpublic repository: CustomObjectRepository;\n\n\tconstructor(parent: Router, repository: CustomObjectRepository) {\n\t\tsuper(parent);\n\t\tthis.repository = repository;\n\t}\n\n\tgetBasePath() {\n\t\treturn \"custom-objects\";\n\t}\n\n\textraRoutes(router: Router) {\n\t\trouter.get(\"/:container\", this.getWithContainer.bind(this));\n\t\trouter.get(\"/:container/:key\", this.getWithContainerAndKey.bind(this));\n\t\trouter.post(\"/:container/:key\", this.createWithContainerAndKey.bind(this));\n\t\trouter.delete(\n\t\t\t\"/:container/:key\",\n\t\t\tthis.deleteWithContainerAndKey.bind(this),\n\t\t);\n\t}\n\n\tgetWithContainer(request: Request, response: Response) {\n\t\tconst limit = this._parseParam(request.query.limit);\n\t\tconst offset = this._parseParam(request.query.offset);\n\n\t\tconst result = this.repository.queryWithContainer(\n\t\t\tgetRepositoryContext(request),\n\t\t\trequest.params.container,\n\t\t\t{\n\t\t\t\texpand: this._parseParam(request.query.expand),\n\t\t\t\twhere: this._parseParam(request.query.where),\n\t\t\t\tlimit: limit !== undefined ? Number(limit) : undefined,\n\t\t\t\toffset: offset !== undefined ? Number(offset) : undefined,\n\t\t\t},\n\t\t);\n\n\t\tresponse.status(200).send(result);\n\t}\n\n\tgetWithContainerAndKey(request: Request, response: Response) {\n\t\tconst result = this.repository.getWithContainerAndKey(\n\t\t\tgetRepositoryContext(request),\n\t\t\trequest.params.container,\n\t\t\trequest.params.key,\n\t\t);\n\n\t\tif (!result) {\n\t\t\tresponse.status(404).send({ statusCode: 404 });\n\t\t\treturn;\n\t\t}\n\t\tresponse.status(200).send(result);\n\t}\n\n\tcreateWithContainerAndKey(request: Request, response: Response) {\n\t\tconst draft: CustomObjectDraft = {\n\t\t\t...request.body,\n\t\t\tkey: request.params.key,\n\t\t\tcontainer: request.params.container,\n\t\t};\n\n\t\tconst result = this.repository.create(getRepositoryContext(request), draft);\n\t\tresponse.status(200).send(result);\n\t}\n\n\tdeleteWithContainerAndKey(request: Request, response: Response) {\n\t\tconst current = this.repository.getWithContainerAndKey(\n\t\t\tgetRepositoryContext(request),\n\t\t\trequest.params.container,\n\t\t\trequest.params.key,\n\t\t);\n\n\t\tif (!current) {\n\t\t\tresponse.status(404).send({ statusCode: 404 });\n\t\t\treturn;\n\t\t}\n\n\t\tconst result = this.repository.delete(\n\t\t\tgetRepositoryContext(request),\n\t\t\tcurrent.id,\n\t\t);\n\n\t\tresponse.status(200).send(result);\n\t}\n}\n","import type { CustomerSignInResult } from \"@commercetools/platform-sdk\";\nimport type { Request, Response, Router } from \"express\";\nimport type { CustomerRepository } from \"../repositories/customer/index.ts\";\nimport { getRepositoryContext } from \"../repositories/helpers.ts\";\nimport AbstractService from \"./abstract.ts\";\n\nexport class CustomerService extends AbstractService {\n\tpublic repository: CustomerRepository;\n\n\tconstructor(parent: Router, repository: CustomerRepository) {\n\t\tsuper(parent);\n\t\tthis.repository = repository;\n\t}\n\n\tgetBasePath() {\n\t\treturn \"customers\";\n\t}\n\n\textraRoutes(parent: Router) {\n\t\tparent.post(\"/password-token\", this.passwordResetToken.bind(this));\n\t\tparent.post(\"/password/reset\", this.passwordReset.bind(this));\n\t\tparent.post(\"/email-token\", this.confirmEmailToken.bind(this));\n\t}\n\n\tpost(request: Request, response: Response) {\n\t\tconst draft = request.body;\n\t\tconst resource = this.repository.create(\n\t\t\tgetRepositoryContext(request),\n\t\t\tdraft,\n\t\t);\n\t\tconst expanded = this._expandWithId(request, resource.id);\n\n\t\tconst result: CustomerSignInResult = {\n\t\t\tcustomer: expanded,\n\t\t};\n\t\tresponse.status(this.createStatusCode).send(result);\n\t}\n\n\tpasswordResetToken(request: Request, response: Response) {\n\t\tconst customer = this.repository.passwordResetToken(\n\t\t\tgetRepositoryContext(request),\n\t\t\trequest.body,\n\t\t);\n\n\t\tresponse.status(200).send(customer);\n\t}\n\n\tpasswordReset(request: Request, response: Response) {\n\t\tconst customer = this.repository.passwordReset(\n\t\t\tgetRepositoryContext(request),\n\t\t\trequest.body,\n\t\t);\n\n\t\tresponse.status(200).send(customer);\n\t}\n\n\tconfirmEmailToken(request: Request, response: Response) {\n\t\tconst id = request.body.id;\n\t\tconst token = this.repository.verifyEmailToken(\n\t\t\tgetRepositoryContext(request),\n\t\t\tid,\n\t\t);\n\t\tresponse.status(200).send(token);\n\t}\n}\n","import type { Router } from \"express\";\nimport type { CustomerGroupRepository } from \"../repositories/customer-group.ts\";\nimport AbstractService from \"./abstract.ts\";\n\nexport class CustomerGroupService extends AbstractService {\n\tpublic repository: CustomerGroupRepository;\n\n\tconstructor(parent: Router, repository: CustomerGroupRepository) {\n\t\tsuper(parent);\n\t\tthis.repository = repository;\n\t}\n\n\tgetBasePath() {\n\t\treturn \"customer-groups\";\n\t}\n}\n","import type { Router } from \"express\";\nimport type { DiscountCodeRepository } from \"../repositories/discount-code/index.ts\";\nimport AbstractService from \"./abstract.ts\";\n\nexport class DiscountCodeService extends AbstractService {\n\tpublic repository: DiscountCodeRepository;\n\n\tconstructor(parent: Router, repository: DiscountCodeRepository) {\n\t\tsuper(parent);\n\t\tthis.repository = repository;\n\t}\n\n\tgetBasePath() {\n\t\treturn \"discount-codes\";\n\t}\n}\n","import type { Router } from \"express\";\nimport type { DiscountGroupRepository } from \"../repositories/discount-group/index.ts\";\nimport AbstractService from \"./abstract.ts\";\n\nexport class DiscountGroupService extends AbstractService {\n\tpublic repository: DiscountGroupRepository;\n\n\tconstructor(parent: Router, repository: DiscountGroupRepository) {\n\t\tsuper(parent);\n\t\tthis.repository = repository;\n\t}\n\n\tgetBasePath() {\n\t\treturn \"discount-groups\";\n\t}\n}\n","import type { Router } from \"express\";\nimport type { ExtensionRepository } from \"../repositories/extension.ts\";\nimport AbstractService from \"./abstract.ts\";\n\nexport class ExtensionServices extends AbstractService {\n\tpublic repository: ExtensionRepository;\n\n\tconstructor(parent: Router, repository: ExtensionRepository) {\n\t\tsuper(parent);\n\t\tthis.repository = repository;\n\t}\n\n\tgetBasePath() {\n\t\treturn \"extensions\";\n\t}\n}\n","import type { Router } from \"express\";\nimport type { InventoryEntryRepository } from \"../repositories/inventory-entry/index.ts\";\nimport AbstractService from \"./abstract.ts\";\n\nexport class InventoryEntryService extends AbstractService {\n\tpublic repository: InventoryEntryRepository;\n\n\tconstructor(parent: Router, repository: InventoryEntryRepository) {\n\t\tsuper(parent);\n\t\tthis.repository = repository;\n\t}\n\n\tgetBasePath() {\n\t\treturn \"inventory\";\n\t}\n}\n","import { Router } from \"express\";\nimport type { BusinessUnitRepository } from \"#src/repositories/business-unit.ts\";\nimport AbstractService from \"./abstract.ts\";\n\nexport class MyBusinessUnitService extends AbstractService {\n\tpublic repository: BusinessUnitRepository;\n\n\tconstructor(parent: Router, repository: BusinessUnitRepository) {\n\t\tsuper(parent);\n\t\tthis.repository = repository;\n\t}\n\n\tgetBasePath() {\n\t\treturn \"me\";\n\t}\n\n\tregisterRoutes(parent: Router) {\n\t\t// Overwrite this function to be able to handle /me/business-units path.\n\t\tconst basePath = this.getBasePath();\n\t\tconst router = Router({ mergeParams: true });\n\n\t\tthis.extraRoutes(router);\n\n\t\trouter.get(\"/business-units/\", this.get.bind(this));\n\t\trouter.get(\"/business-units/key=:key\", this.getWithKey.bind(this));\n\t\trouter.get(\"/business-units/:id\", this.getWithId.bind(this));\n\n\t\trouter.delete(\"/business-units/key=:key\", this.deleteWithKey.bind(this));\n\t\trouter.delete(\"/business-units/:id\", this.deleteWithId.bind(this));\n\n\t\trouter.post(\"/business-units/\", this.post.bind(this));\n\t\trouter.post(\"/business-units/key=:key\", this.postWithKey.bind(this));\n\t\trouter.post(\"/business-units/:id\", this.postWithId.bind(this));\n\n\t\tparent.use(`/${basePath}`, router);\n\t}\n}\n","import type { Request, Response } from \"express\";\nimport { Router } from \"express\";\nimport type { CartRepository } from \"../repositories/cart/index.ts\";\nimport AbstractService from \"./abstract.ts\";\n\nexport class MyCartService extends AbstractService {\n\tpublic repository: CartRepository;\n\n\tconstructor(parent: Router, repository: CartRepository) {\n\t\tsuper(parent);\n\t\tthis.repository = repository;\n\t}\n\n\tgetBasePath() {\n\t\treturn \"me\";\n\t}\n\n\tregisterRoutes(parent: Router) {\n\t\t// Overwrite this function to be able to handle /me/active-cart path.\n\t\tconst basePath = this.getBasePath();\n\t\tconst router = Router({ mergeParams: true });\n\n\t\tthis.extraRoutes(router);\n\n\t\trouter.get(\"/active-cart\", this.activeCart.bind(this));\n\t\trouter.get(\"/carts/\", this.get.bind(this));\n\t\trouter.get(\"/carts/:id\", this.getWithId.bind(this));\n\n\t\trouter.delete(\"/carts/:id\", this.deleteWithId.bind(this));\n\n\t\trouter.post(\"/carts/\", this.post.bind(this));\n\t\trouter.post(\"/carts/:id\", this.postWithId.bind(this));\n\n\t\tparent.use(`/${basePath}`, router);\n\t}\n\n\tactiveCart(request: Request, response: Response) {\n\t\tconst resource = this.repository.getActiveCart(request.params.projectKey);\n\t\tif (!resource) {\n\t\t\tresponse.status(404).send({\n\t\t\t\tstatusCode: 404,\n\t\t\t\tmessage: \"No active cart exists.\",\n\t\t\t\terrors: [\n\t\t\t\t\t{\n\t\t\t\t\t\tcode: \"ResourceNotFound\",\n\t\t\t\t\t\tmessage: \"No active cart exists.\",\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\t\tresponse.status(200).send(resource);\n\t}\n}\n","import type { Update } from \"@commercetools/platform-sdk\";\nimport type { Request, Response } from \"express\";\nimport { Router } from \"express\";\nimport { updateRequestSchema } from \"#src/schemas/update-request.ts\";\nimport { validateData } from \"#src/validate.ts\";\nimport { hashPassword } from \"../lib/password.ts\";\nimport { getRepositoryContext } from \"../repositories/helpers.ts\";\nimport type { MyCustomerRepository } from \"../repositories/my-customer.ts\";\nimport AbstractService from \"./abstract.ts\";\n\nexport class MyCustomerService extends AbstractService {\n\tpublic repository: MyCustomerRepository;\n\n\tconstructor(parent: Router, repository: MyCustomerRepository) {\n\t\tsuper(parent);\n\t\tthis.repository = repository;\n\t}\n\n\tgetBasePath() {\n\t\treturn \"me\";\n\t}\n\n\tregisterRoutes(parent: Router) {\n\t\t// Overwrite this function to be able to handle /me path.\n\t\tconst basePath = this.getBasePath();\n\t\tconst router = Router({ mergeParams: true });\n\n\t\tthis.extraRoutes(router);\n\n\t\trouter.get(\"\", this.getMe.bind(this));\n\t\trouter.post(\"\", this.updateMe.bind(this));\n\t\trouter.delete(\"\", this.deleteMe.bind(this));\n\n\t\trouter.post(\"/signup\", this.signUp.bind(this));\n\n\t\trouter.post(\"/login\", this.signIn.bind(this));\n\t\trouter.post(\"/password\", this.changePassword.bind(this));\n\t\trouter.post(\"/password/reset\", this.resetPassword.bind(this));\n\t\trouter.post(\"/email/confirm\", this.emailConfirm.bind(this));\n\n\t\tparent.use(`/${basePath}`, router);\n\t}\n\n\tgetMe(request: Request, response: Response) {\n\t\tconst resource = this.repository.getMe(getRepositoryContext(request));\n\t\tif (!resource) {\n\t\t\tresponse.status(404).send({ statusCode: 404 });\n\t\t\treturn;\n\t\t}\n\t\tresponse.status(200).send(resource);\n\t}\n\n\tupdateMe(request: Request, response: Response) {\n\t\tconst resource = this.repository.getMe(getRepositoryContext(request));\n\n\t\tif (!resource) {\n\t\t\tresponse.status(404).send({ statusCode: 404 });\n\t\t\treturn;\n\t\t}\n\t\tconst updateRequest = validateData<Update>(\n\t\t\trequest.body,\n\t\t\tupdateRequestSchema,\n\t\t);\n\t\tconst updatedResource = this.repository.processUpdateActions(\n\t\t\tgetRepositoryContext(request),\n\t\t\tresource,\n\t\t\tupdateRequest.version,\n\t\t\tupdateRequest.actions,\n\t\t);\n\n\t\tconst result = this._expandWithId(request, updatedResource.id);\n\t\tresponse.status(200).send(result);\n\t}\n\n\tdeleteMe(request: Request, response: Response) {\n\t\tconst resource = this.repository.deleteMe(getRepositoryContext(request));\n\t\tif (!resource) {\n\t\t\tresponse.status(404).send({ statusCode: 404 });\n\t\t\treturn;\n\t\t}\n\n\t\tresponse.status(200).send(resource);\n\t}\n\n\tsignUp(request: Request, response: Response) {\n\t\tconst draft = request.body;\n\t\tconst resource = this.repository.create(\n\t\t\tgetRepositoryContext(request),\n\t\t\tdraft,\n\t\t);\n\t\tconst result = this._expandWithId(request, resource.id);\n\t\tresponse.status(this.createStatusCode).send({ customer: result });\n\t}\n\n\tchangePassword(request: Request, response: Response) {\n\t\tconst customer = this.repository.changePassword(\n\t\t\tgetRepositoryContext(request),\n\t\t\trequest.body,\n\t\t);\n\n\t\tresponse.status(200).send(customer);\n\t}\n\n\tresetPassword(request: Request, response: Response) {\n\t\tconst customer = this.repository.passwordReset(\n\t\t\tgetRepositoryContext(request),\n\t\t\trequest.body,\n\t\t);\n\n\t\tresponse.status(200).send(customer);\n\t}\n\n\temailConfirm(request: Request, response: Response) {\n\t\tconst customer = this.repository.confirmEmail(\n\t\t\tgetRepositoryContext(request),\n\t\t\trequest.body,\n\t\t);\n\n\t\tresponse.status(200).send(customer);\n\t}\n\n\tsignIn(request: Request, response: Response) {\n\t\tconst { email, password } = request.body;\n\t\tconst encodedPassword = hashPassword(password);\n\n\t\tconst result = this.repository.query(getRepositoryContext(request), {\n\t\t\twhere: [`email = \"${email}\"`, `password = \"${encodedPassword}\"`],\n\t\t});\n\n\t\tif (result.count === 0) {\n\t\t\tresponse.status(400).send({\n\t\t\t\tmessage: \"Account with the given credentials not found.\",\n\t\t\t\terrors: [\n\t\t\t\t\t{\n\t\t\t\t\t\tcode: \"InvalidCredentials\",\n\t\t\t\t\t\tmessage: \"Account with the given credentials not found.\",\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\n\t\tresponse.status(200).send({ customer: result.results[0] });\n\t}\n}\n","import { Router } from \"express\";\nimport type { MyOrderRepository } from \"../repositories/my-order.ts\";\nimport AbstractService from \"./abstract.ts\";\n\nexport class MyOrderService extends AbstractService {\n\tpublic repository: MyOrderRepository;\n\n\tconstructor(parent: Router, repository: MyOrderRepository) {\n\t\tsuper(parent);\n\t\tthis.repository = repository;\n\t}\n\n\tgetBasePath() {\n\t\treturn \"me\";\n\t}\n\n\tregisterRoutes(parent: Router) {\n\t\t// Overwrite this function to be able to handle /me/active-cart path.\n\t\tconst basePath = this.getBasePath();\n\t\tconst router = Router({ mergeParams: true });\n\n\t\tthis.extraRoutes(router);\n\n\t\trouter.get(\"/orders/\", this.get.bind(this));\n\t\trouter.get(\"/orders/:id\", this.getWithId.bind(this));\n\n\t\trouter.delete(\"/orders/:id\", this.deleteWithId.bind(this));\n\n\t\trouter.post(\"/orders/\", this.post.bind(this));\n\t\trouter.post(\"/orders/:id\", this.postWithId.bind(this));\n\n\t\tparent.use(`/${basePath}`, router);\n\t}\n}\n","import type { Router } from \"express\";\nimport type { PaymentRepository } from \"../repositories/payment/index.ts\";\nimport AbstractService from \"./abstract.ts\";\n\nexport class MyPaymentService extends AbstractService {\n\tpublic repository: PaymentRepository;\n\n\tconstructor(parent: Router, repository: PaymentRepository) {\n\t\tsuper(parent);\n\t\tthis.repository = repository;\n\t}\n\n\tgetBasePath() {\n\t\treturn \"me/payments\";\n\t}\n}\n","import type { Router } from \"express\";\nimport type { ShoppingListRepository } from \"../repositories/shopping-list/index.ts\";\nimport AbstractService from \"./abstract.ts\";\n\nexport class MyShoppingListService extends AbstractService {\n\tpublic repository: ShoppingListRepository;\n\n\tconstructor(parent: Router, repository: ShoppingListRepository) {\n\t\tsuper(parent);\n\t\tthis.repository = repository;\n\t}\n\n\tgetBasePath() {\n\t\treturn \"me/shopping-lists\";\n\t}\n}\n","import type { Request, Response, Router } from \"express\";\nimport { getRepositoryContext } from \"../repositories/helpers.ts\";\nimport type { OrderRepository } from \"../repositories/order/index.ts\";\nimport AbstractService from \"./abstract.ts\";\n\nexport class OrderService extends AbstractService {\n\tpublic repository: OrderRepository;\n\n\tconstructor(parent: Router, repository: OrderRepository) {\n\t\tsuper(parent);\n\t\tthis.repository = repository;\n\t}\n\n\tgetBasePath() {\n\t\treturn \"orders\";\n\t}\n\n\textraRoutes(router: Router) {\n\t\trouter.post(\"/import\", this.import.bind(this));\n\t\trouter.get(\n\t\t\t\"/order-number=:orderNumber\",\n\t\t\tthis.getWithOrderNumber.bind(this),\n\t\t);\n\t}\n\n\timport(request: Request, response: Response) {\n\t\tconst importDraft = request.body;\n\t\tconst resource = this.repository.import(\n\t\t\tgetRepositoryContext(request),\n\t\t\timportDraft,\n\t\t);\n\t\tresponse.status(200).send(resource);\n\t}\n\n\tgetWithOrderNumber(request: Request, response: Response) {\n\t\tconst orderNumber = request.params.orderNumber;\n\t\tconst resource = this.repository.getWithOrderNumber(\n\t\t\tgetRepositoryContext(request),\n\t\t\torderNumber,\n\n\t\t\t// @ts-expect-error\n\t\t\trequest.query,\n\t\t);\n\t\tif (resource) {\n\t\t\tresponse.status(200).send(resource);\n\t\t\treturn;\n\t\t}\n\t\tresponse.status(404).send({\n\t\t\tstatusCode: 404,\n\t\t\tmessage: `The Resource with key '${orderNumber}' was not found.`,\n\t\t\terrors: [\n\t\t\t\t{\n\t\t\t\t\tcode: \"ResourceNotFound\",\n\t\t\t\t\tmessage: `The Resource with key '${orderNumber}' was not found.`,\n\t\t\t\t},\n\t\t\t],\n\t\t});\n\t}\n}\n","import type { Router } from \"express\";\nimport type { PaymentRepository } from \"../repositories/payment/index.ts\";\nimport AbstractService from \"./abstract.ts\";\n\nexport class PaymentService extends AbstractService {\n\tpublic repository: PaymentRepository;\n\n\tconstructor(parent: Router, repository: PaymentRepository) {\n\t\tsuper(parent);\n\t\tthis.repository = repository;\n\t}\n\n\tgetBasePath() {\n\t\treturn \"payments\";\n\t}\n}\n","import type { Request, Response, Router } from \"express\";\nimport { getRepositoryContext } from \"#src/repositories/helpers.ts\";\nimport type { ProductRepository } from \"../repositories/product/index.ts\";\nimport AbstractService from \"./abstract.ts\";\n\nexport class ProductService extends AbstractService {\n\tpublic repository: ProductRepository;\n\n\tconstructor(parent: Router, repository: ProductRepository) {\n\t\tsuper(parent);\n\t\tthis.repository = repository;\n\t}\n\n\tgetBasePath() {\n\t\treturn \"products\";\n\t}\n\n\textraRoutes(router: Router) {\n\t\trouter.post(\"/search\", this.search.bind(this));\n\t}\n\n\tsearch(request: Request, response: Response) {\n\t\tconst searchBody = request.body;\n\t\tconst resource = this.repository.search(\n\t\t\tgetRepositoryContext(request),\n\t\t\tsearchBody,\n\t\t);\n\t\tresponse.status(200).send(resource);\n\t}\n}\n","import type { Router } from \"express\";\nimport type { ProductDiscountRepository } from \"../repositories/product-discount.ts\";\nimport AbstractService from \"./abstract.ts\";\n\nexport class ProductDiscountService extends AbstractService {\n\tpublic repository: ProductDiscountRepository;\n\n\tconstructor(parent: Router, repository: ProductDiscountRepository) {\n\t\tsuper(parent);\n\t\tthis.repository = repository;\n\t}\n\n\tgetBasePath() {\n\t\treturn \"product-discounts\";\n\t}\n}\n","import type { Request, Response, Router } from \"express\";\nimport { queryParamsArray, queryParamsValue } from \"../helpers.ts\";\nimport { getRepositoryContext } from \"../repositories/helpers.ts\";\nimport type {\n\tProductProjectionQueryParams,\n\tProductProjectionRepository,\n} from \"./../repositories/product-projection.ts\";\nimport AbstractService from \"./abstract.ts\";\n\nexport class ProductProjectionService extends AbstractService {\n\tpublic repository: ProductProjectionRepository;\n\n\tconstructor(parent: Router, repository: ProductProjectionRepository) {\n\t\tsuper(parent);\n\t\tthis.repository = repository;\n\t}\n\n\tgetBasePath() {\n\t\treturn \"product-projections\";\n\t}\n\n\textraRoutes(router: Router) {\n\t\trouter.get(\"/search\", this.search.bind(this));\n\t}\n\n\tget(request: Request, response: Response) {\n\t\tconst limit = this._parseParam(request.query.limit);\n\t\tconst offset = this._parseParam(request.query.offset);\n\n\t\tconst result = this.repository.query(getRepositoryContext(request), {\n\t\t\t...request.query,\n\t\t\texpand: this._parseParam(request.query.expand),\n\t\t\twhere: this._parseParam(request.query.where),\n\t\t\tlimit: limit !== undefined ? Number(limit) : undefined,\n\t\t\toffset: offset !== undefined ? Number(offset) : undefined,\n\t\t});\n\t\tresponse.status(200).send(result);\n\t}\n\n\tsearch(request: Request, response: Response) {\n\t\tconst query = request.query;\n\t\tconst searchParams: ProductProjectionQueryParams = {\n\t\t\tfilter: queryParamsArray(query.filter),\n\t\t\t\"filter.query\": queryParamsArray(query[\"filter.query\"]),\n\t\t\tfacet: queryParamsArray(query.facet),\n\t\t\texpand: queryParamsArray(query.expand),\n\t\t\tstaged: queryParamsValue(query.staged) === \"true\",\n\t\t\tlocaleProjection: queryParamsValue(query.localeProjection),\n\t\t\tstoreProjection: queryParamsValue(query.storeProjection),\n\t\t\tpriceChannel: queryParamsValue(query.priceChannel),\n\t\t\tpriceCountry: queryParamsValue(query.priceCountry),\n\t\t\tpriceCurrency: queryParamsValue(query.priceCurrency),\n\t\t\tpriceCustomerGroup: queryParamsValue(query.priceCustomerGroup),\n\t\t\toffset: query.offset ? Number(queryParamsValue(query.offset)) : undefined,\n\t\t\tlimit: query.limit ? Number(queryParamsValue(query.limit)) : undefined,\n\t\t};\n\t\tconst resource = this.repository.search(\n\t\t\tgetRepositoryContext(request),\n\t\t\tsearchParams,\n\t\t);\n\t\tresponse.status(200).send(resource);\n\t}\n}\n","import type { Router } from \"express\";\nimport type { ProductSelectionRepository } from \"../repositories/product-selection.ts\";\nimport AbstractService from \"./abstract.ts\";\n\nexport class ProductSelectionService extends AbstractService {\n\tpublic repository: ProductSelectionRepository;\n\n\tconstructor(parent: Router, repository: ProductSelectionRepository) {\n\t\tsuper(parent);\n\t\tthis.repository = repository;\n\t}\n\n\tgetBasePath() {\n\t\treturn \"product-selections\";\n\t}\n}\n","import type { Router } from \"express\";\nimport type { ProductTypeRepository } from \"../repositories/product-type.ts\";\nimport AbstractService from \"./abstract.ts\";\n\nexport class ProductTypeService extends AbstractService {\n\tpublic repository: ProductTypeRepository;\n\n\tconstructor(parent: Router, repository: ProductTypeRepository) {\n\t\tsuper(parent);\n\t\tthis.repository = repository;\n\t}\n\n\tgetBasePath() {\n\t\treturn \"product-types\";\n\t}\n}\n","import type { Router } from \"express\";\nimport type { QuoteRepository } from \"#src/repositories/quote/index.ts\";\nimport AbstractService from \"./abstract.ts\";\n\nexport class QuoteService extends AbstractService {\n\tpublic repository: QuoteRepository;\n\n\tconstructor(parent: Router, repository: QuoteRepository) {\n\t\tsuper(parent);\n\t\tthis.repository = repository;\n\t}\n\n\tgetBasePath() {\n\t\treturn \"quotes\";\n\t}\n}\n","import type { Router } from \"express\";\nimport type { QuoteRequestRepository } from \"#src/repositories/quote-request/index.ts\";\nimport AbstractService from \"./abstract.ts\";\n\nexport class QuoteRequestService extends AbstractService {\n\tpublic repository: QuoteRequestRepository;\n\n\tconstructor(parent: Router, repository: QuoteRequestRepository) {\n\t\tsuper(parent);\n\t\tthis.repository = repository;\n\t}\n\n\tgetBasePath() {\n\t\treturn \"quote-requests\";\n\t}\n}\n","import type { Router } from \"express\";\nimport type { StagedQuoteRepository } from \"#src/repositories/quote-staged/index.ts\";\nimport AbstractService from \"./abstract.ts\";\n\nexport class StagedQuoteService extends AbstractService {\n\tpublic repository: StagedQuoteRepository;\n\n\tconstructor(parent: Router, repository: StagedQuoteRepository) {\n\t\tsuper(parent);\n\t\tthis.repository = repository;\n\t}\n\n\tgetBasePath() {\n\t\treturn \"staged-quotes\";\n\t}\n}\n","import type { Router } from \"express\";\nimport type { RecurrencePolicyRepository } from \"../repositories/recurrence-policy/index.ts\";\nimport AbstractService from \"./abstract.ts\";\n\nexport class RecurrencePolicyService extends AbstractService {\n\tpublic repository: RecurrencePolicyRepository;\n\n\tconstructor(parent: Router, repository: RecurrencePolicyRepository) {\n\t\tsuper(parent);\n\t\tthis.repository = repository;\n\t}\n\n\tgetBasePath() {\n\t\treturn \"recurrence-policies\";\n\t}\n}\n","import type { Router } from \"express\";\nimport type { RecurringOrderRepository } from \"../repositories/recurring-order/index.ts\";\nimport AbstractService from \"./abstract.ts\";\n\nexport class RecurringOrderService extends AbstractService {\n\tpublic repository: RecurringOrderRepository;\n\n\tconstructor(parent: Router, repository: RecurringOrderRepository) {\n\t\tsuper(parent);\n\t\tthis.repository = repository;\n\t}\n\n\tgetBasePath() {\n\t\treturn \"recurring-orders\";\n\t}\n}\n","import type { Router } from \"express\";\nimport type { ReviewRepository } from \"../repositories/review.ts\";\nimport AbstractService from \"./abstract.ts\";\n\nexport class ReviewService extends AbstractService {\n\tpublic repository: ReviewRepository;\n\n\tconstructor(parent: Router, repository: ReviewRepository) {\n\t\tsuper(parent);\n\t\tthis.repository = repository;\n\t}\n\n\tgetBasePath() {\n\t\treturn \"reviews\";\n\t}\n}\n","import type { Request, Response, Router } from \"express\";\nimport { queryParamsValue } from \"../helpers.ts\";\nimport { getRepositoryContext } from \"../repositories/helpers.ts\";\nimport type { ShippingMethodRepository } from \"../repositories/shipping-method/index.ts\";\nimport AbstractService from \"./abstract.ts\";\n\nexport class ShippingMethodService extends AbstractService {\n\tpublic repository: ShippingMethodRepository;\n\n\tconstructor(parent: Router, repository: ShippingMethodRepository) {\n\t\tsuper(parent);\n\t\tthis.repository = repository;\n\t\tthis.registerRoutes(parent);\n\t}\n\n\tgetBasePath() {\n\t\treturn \"shipping-methods\";\n\t}\n\n\textraRoutes(parent: Router) {\n\t\tparent.get(\"/matching-cart\", this.matchingCart.bind(this));\n\t}\n\n\tmatchingCart(request: Request, response: Response) {\n\t\tconst cartId = queryParamsValue(request.query.cartId);\n\t\tif (!cartId) {\n\t\t\tresponse.status(400).send();\n\t\t\treturn;\n\t\t}\n\t\tconst result = this.repository.matchingCart(\n\t\t\tgetRepositoryContext(request),\n\t\t\tcartId,\n\t\t\t{\n\t\t\t\texpand: this._parseParam(request.query.expand),\n\t\t\t},\n\t\t);\n\t\tresponse.status(200).send(result);\n\t\treturn;\n\t}\n}\n","import type { Router } from \"express\";\nimport type { ShoppingListRepository } from \"../repositories/shopping-list/index.ts\";\nimport AbstractService from \"./abstract.ts\";\n\nexport class ShoppingListService extends AbstractService {\n\tpublic repository: ShoppingListRepository;\n\n\tconstructor(parent: Router, repository: ShoppingListRepository) {\n\t\tsuper(parent);\n\t\tthis.repository = repository;\n\t}\n\n\tgetBasePath() {\n\t\treturn \"shopping-lists\";\n\t}\n}\n","import type { Router } from \"express\";\nimport type { StandAlonePriceRepository } from \"../repositories/standalone-price.ts\";\nimport AbstractService from \"./abstract.ts\";\n\nexport class StandAlonePriceService extends AbstractService {\n\tpublic repository: StandAlonePriceRepository;\n\n\tconstructor(parent: Router, repository: StandAlonePriceRepository) {\n\t\tsuper(parent);\n\t\tthis.repository = repository;\n\t}\n\n\tgetBasePath() {\n\t\treturn \"standalone-prices\";\n\t}\n}\n","import type { Router } from \"express\";\nimport type { StateRepository } from \"../repositories/state.ts\";\nimport AbstractService from \"./abstract.ts\";\n\nexport class StateService extends AbstractService {\n\tpublic repository: StateRepository;\n\n\tconstructor(parent: Router, repository: StateRepository) {\n\t\tsuper(parent);\n\t\tthis.repository = repository;\n\t}\n\n\tgetBasePath() {\n\t\treturn \"states\";\n\t}\n}\n","import type { Router } from \"express\";\nimport type { StoreRepository } from \"../repositories/store.ts\";\nimport AbstractService from \"./abstract.ts\";\n\nexport class StoreService extends AbstractService {\n\tpublic repository: StoreRepository;\n\n\tconstructor(parent: Router, repository: StoreRepository) {\n\t\tsuper(parent);\n\t\tthis.repository = repository;\n\t}\n\n\tgetBasePath() {\n\t\treturn \"stores\";\n\t}\n}\n","import type { Router } from \"express\";\nimport type { SubscriptionRepository } from \"../repositories/subscription.ts\";\nimport AbstractService from \"./abstract.ts\";\n\nexport class SubscriptionService extends AbstractService {\n\tpublic repository: SubscriptionRepository;\n\n\tconstructor(parent: Router, repository: SubscriptionRepository) {\n\t\tsuper(parent);\n\t\tthis.repository = repository;\n\t}\n\n\tgetBasePath() {\n\t\treturn \"subscriptions\";\n\t}\n}\n","import type { Router } from \"express\";\nimport type { TaxCategoryRepository } from \"../repositories/tax-category/index.ts\";\nimport AbstractService from \"./abstract.ts\";\n\nexport class TaxCategoryService extends AbstractService {\n\tpublic repository: TaxCategoryRepository;\n\n\tconstructor(parent: Router, repository: TaxCategoryRepository) {\n\t\tsuper(parent);\n\t\tthis.repository = repository;\n\t}\n\n\tgetBasePath() {\n\t\treturn \"tax-categories\";\n\t}\n}\n","import type { Router } from \"express\";\nimport type { TypeRepository } from \"../repositories/type/index.ts\";\nimport AbstractService from \"./abstract.ts\";\n\nexport class TypeService extends AbstractService {\n\tpublic repository: TypeRepository;\n\n\tconstructor(parent: Router, repository: TypeRepository) {\n\t\tsuper(parent);\n\t\tthis.repository = repository;\n\t}\n\n\tgetBasePath() {\n\t\treturn \"types\";\n\t}\n}\n","import type { Router } from \"express\";\nimport type { ZoneRepository } from \"../repositories/zone.ts\";\nimport AbstractService from \"./abstract.ts\";\n\nexport class ZoneService extends AbstractService {\n\tpublic repository: ZoneRepository;\n\n\tconstructor(parent: Router, repository: ZoneRepository) {\n\t\tsuper(parent);\n\t\tthis.repository = repository;\n\t}\n\n\tgetBasePath() {\n\t\treturn \"zones\";\n\t}\n}\n","import type { createRepositories } from \"../repositories/index.ts\";\nimport { AsAssociateService } from \"./as-associate.ts\";\nimport { AssociateRoleServices } from \"./associate-roles.ts\";\nimport { AttributeGroupService } from \"./attribute-group.ts\";\nimport { BusinessUnitServices } from \"./business-units.ts\";\nimport { CartService } from \"./cart.ts\";\nimport { CartDiscountService } from \"./cart-discount.ts\";\nimport { CategoryServices } from \"./category.ts\";\nimport { ChannelService } from \"./channel.ts\";\nimport { CustomObjectService } from \"./custom-object.ts\";\nimport { CustomerService } from \"./customer.ts\";\nimport { CustomerGroupService } from \"./customer-group.ts\";\nimport { DiscountCodeService } from \"./discount-code.ts\";\nimport { DiscountGroupService } from \"./discount-group.ts\";\nimport { ExtensionServices } from \"./extension.ts\";\nimport { InventoryEntryService } from \"./inventory-entry.ts\";\nimport { MyBusinessUnitService } from \"./my-business-unit.ts\";\nimport { MyCartService } from \"./my-cart.ts\";\nimport { MyCustomerService } from \"./my-customer.ts\";\nimport { MyOrderService } from \"./my-order.ts\";\nimport { MyPaymentService } from \"./my-payment.ts\";\nimport { MyShoppingListService } from \"./my-shopping-list.ts\";\nimport { OrderService } from \"./order.ts\";\nimport { PaymentService } from \"./payment.ts\";\nimport { ProductService } from \"./product.ts\";\nimport { ProductDiscountService } from \"./product-discount.ts\";\nimport { ProductProjectionService } from \"./product-projection.ts\";\nimport { ProductSelectionService } from \"./product-selection.ts\";\nimport { ProductTypeService } from \"./product-type.ts\";\nimport { QuoteService } from \"./quote.ts\";\nimport { QuoteRequestService } from \"./quote-request.ts\";\nimport { StagedQuoteService } from \"./quote-staged.ts\";\nimport { RecurrencePolicyService } from \"./recurrence-policy.ts\";\nimport { RecurringOrderService } from \"./recurring-order.ts\";\nimport { ReviewService } from \"./reviews.ts\";\nimport { ShippingMethodService } from \"./shipping-method.ts\";\nimport { ShoppingListService } from \"./shopping-list.ts\";\nimport { StandAlonePriceService } from \"./standalone-price.ts\";\nimport { StateService } from \"./state.ts\";\nimport { StoreService } from \"./store.ts\";\nimport { SubscriptionService } from \"./subscription.ts\";\nimport { TaxCategoryService } from \"./tax-category.ts\";\nimport { TypeService } from \"./type.ts\";\nimport { ZoneService } from \"./zone.ts\";\n\nexport const createServices = (\n\trouter: any,\n\trepos: ReturnType<typeof createRepositories>,\n) => ({\n\t\"associate-role\": new AssociateRoleServices(router, repos[\"associate-role\"]),\n\t\"as-associate\": new AsAssociateService(router, repos[\"as-associate\"]),\n\t\"business-unit\": new BusinessUnitServices(router, repos[\"business-unit\"]),\n\tcategory: new CategoryServices(router, repos.category),\n\tcart: new CartService(router, repos.cart, repos.order),\n\t\"cart-discount\": new CartDiscountService(router, repos[\"cart-discount\"]),\n\tcustomer: new CustomerService(router, repos.customer),\n\tchannel: new ChannelService(router, repos.channel),\n\t\"customer-group\": new CustomerGroupService(router, repos[\"customer-group\"]),\n\t\"discount-code\": new DiscountCodeService(router, repos[\"discount-code\"]),\n\t\"discount-group\": new DiscountGroupService(router, repos[\"discount-group\"]),\n\textension: new ExtensionServices(router, repos.extension),\n\t\"inventory-entry\": new InventoryEntryService(\n\t\trouter,\n\t\trepos[\"inventory-entry\"],\n\t),\n\t\"key-value-document\": new CustomObjectService(\n\t\trouter,\n\t\trepos[\"key-value-document\"],\n\t),\n\torder: new OrderService(router, repos.order),\n\tpayment: new PaymentService(router, repos.payment),\n\t\"standalone-price\": new StandAlonePriceService(\n\t\trouter,\n\t\trepos[\"standalone-price\"],\n\t),\n\t\"my-cart\": new MyCartService(router, repos[\"my-cart\"]),\n\t\"my-order\": new MyOrderService(router, repos[\"my-order\"]),\n\t\"my-customer\": new MyCustomerService(router, repos[\"my-customer\"]),\n\t\"my-business-unit\": new MyBusinessUnitService(router, repos[\"business-unit\"]),\n\t\"my-payment\": new MyPaymentService(router, repos[\"my-payment\"]),\n\t\"my-shopping-list\": new MyShoppingListService(\n\t\trouter,\n\t\trepos[\"my-shopping-list\"],\n\t),\n\t\"shipping-method\": new ShippingMethodService(\n\t\trouter,\n\t\trepos[\"shipping-method\"],\n\t),\n\t\"product-type\": new ProductTypeService(router, repos[\"product-type\"]),\n\tproduct: new ProductService(router, repos.product),\n\t\"product-discount\": new ProductDiscountService(\n\t\trouter,\n\t\trepos[\"product-discount\"],\n\t),\n\t\"product-projection\": new ProductProjectionService(\n\t\trouter,\n\t\trepos[\"product-projection\"],\n\t),\n\t\"product-selection\": new ProductSelectionService(\n\t\trouter,\n\t\trepos[\"product-selection\"],\n\t),\n\tquotes: new QuoteService(router, repos.quote),\n\t\"quote-request\": new QuoteRequestService(router, repos[\"quote-request\"]),\n\t\"recurrence-policy\": new RecurrencePolicyService(\n\t\trouter,\n\t\trepos[\"recurrence-policy\"],\n\t),\n\t\"recurring-order\": new RecurringOrderService(\n\t\trouter,\n\t\trepos[\"recurring-order\"],\n\t),\n\treviews: new ReviewService(router, repos.review),\n\t\"shopping-list\": new ShoppingListService(router, repos[\"shopping-list\"]),\n\t\"staged-quote\": new StagedQuoteService(router, repos[\"staged-quote\"]),\n\tstate: new StateService(router, repos.state),\n\tstore: new StoreService(router, repos.store),\n\tsubscription: new SubscriptionService(router, repos.subscription),\n\t\"tax-category\": new TaxCategoryService(router, repos[\"tax-category\"]),\n\t\"attribute-group\": new AttributeGroupService(\n\t\trouter,\n\t\trepos[\"attribute-group\"],\n\t),\n\ttype: new TypeService(router, repos.type),\n\tzone: new ZoneService(router, repos.zone),\n});\n","import type { Update } from \"@commercetools/platform-sdk\";\nimport type { Request, Response, Router } from \"express\";\nimport { updateRequestSchema } from \"#src/schemas/update-request.ts\";\nimport { validateData } from \"#src/validate.ts\";\nimport { getRepositoryContext } from \"../repositories/helpers.ts\";\nimport type { ProjectRepository } from \"../repositories/project.ts\";\n\nexport class ProjectService {\n\tpublic repository: ProjectRepository;\n\n\tconstructor(parent: Router, repository: ProjectRepository) {\n\t\tthis.repository = repository;\n\t\tthis.registerRoutes(parent);\n\t}\n\n\tregisterRoutes(parent: Router) {\n\t\tparent.get(\"\", this.get.bind(this));\n\t\tparent.post(\"\", this.post.bind(this));\n\t}\n\n\tget(request: Request, response: Response) {\n\t\tconst project = this.repository.get(getRepositoryContext(request));\n\t\tresponse.status(200).send(project);\n\t}\n\n\tpost(request: Request, response: Response) {\n\t\tconst updateRequest = validateData<Update>(\n\t\t\trequest.body,\n\t\t\tupdateRequestSchema,\n\t\t);\n\t\tconst project = this.repository.get(getRepositoryContext(request));\n\n\t\tif (!project) {\n\t\t\tresponse.status(404).send({ statusCode: 404 });\n\t\t\treturn;\n\t\t}\n\n\t\tconst updatedResource = this.repository.processUpdateActions(\n\t\t\tgetRepositoryContext(request),\n\t\t\tproject,\n\t\t\tupdateRequest.version,\n\t\t\tupdateRequest.actions,\n\t\t);\n\n\t\tresponse.status(200).send(updatedResource);\n\t}\n}\n","import type {\n\tBaseResource,\n\tProject,\n\tQueryParam,\n\tResourceIdentifier,\n} from \"@commercetools/platform-sdk\";\nimport type {\n\tPagedQueryResponseMap,\n\tResourceMap,\n\tResourceType,\n} from \"../types.ts\";\n\nexport type GetParams = {\n\texpand?: string[];\n};\n\nexport type QueryParams = {\n\texpand?: string | string[];\n\tsort?: string | string[];\n\tlimit?: number;\n\toffset?: number;\n\twithTotal?: boolean;\n\twhere?: string | string[];\n\t[key: string]: QueryParam;\n};\n\nexport abstract class AbstractStorage {\n\tabstract clear(): void;\n\n\tabstract all<RT extends ResourceType>(\n\t\tprojectKey: string,\n\t\ttypeId: RT,\n\t): Array<ResourceMap[RT]>;\n\n\tabstract add<RT extends ResourceType>(\n\t\tprojectKey: string,\n\t\ttypeId: RT,\n\t\tobj: ResourceMap[RT],\n\t): ResourceMap[RT];\n\n\tabstract get<RT extends ResourceType>(\n\t\tprojectKey: string,\n\t\ttypeId: RT,\n\t\tid: string,\n\t\tparams?: GetParams,\n\t): ResourceMap[RT] | null;\n\n\tabstract getByKey<RT extends ResourceType>(\n\t\tprojectKey: string,\n\t\ttypeId: RT,\n\t\tkey: string,\n\t\tparams: GetParams,\n\t): ResourceMap[RT] | null;\n\n\tabstract addProject(projectKey: string): Project;\n\n\tabstract getProject(projectKey: string): Project;\n\n\tabstract saveProject(project: Project): Project;\n\n\tabstract delete<RT extends ResourceType>(\n\t\tprojectKey: string,\n\t\ttypeId: RT,\n\t\tid: string,\n\t\tparams: GetParams,\n\t): ResourceMap[RT] | null;\n\n\tabstract query<RT extends ResourceType>(\n\t\tprojectKey: string,\n\t\ttypeId: RT,\n\t\tparams: QueryParams,\n\t): PagedQueryResponseMap[RT];\n\n\tabstract getByResourceIdentifier<RT extends ResourceType>(\n\t\tprojectKey: string,\n\t\tidentifier: ResourceIdentifier,\n\t): ResourceMap[RT];\n\n\tabstract expand<T>(\n\t\tprojectKey: string,\n\t\tobj: T,\n\t\tclause: undefined | string | string[],\n\t): T;\n}\n\nexport type ProjectStorage = {\n\t[index in ResourceType]: Map<string, BaseResource>;\n};\n","import assert from \"node:assert\";\nimport type {\n\tAssociateRole,\n\tAttributeGroup,\n\tBusinessUnit,\n\tCart,\n\tCartDiscount,\n\tCategory,\n\tChannel,\n\tCustomer,\n\tCustomerGroup,\n\tCustomObject,\n\tDiscountCode,\n\tDiscountGroup,\n\tExtension,\n\tInvalidInputError,\n\tInvalidJsonInputError,\n\tInventoryEntry,\n\tOrder,\n\tPagedQueryResponse,\n\tPayment,\n\tProduct,\n\tProductDiscount,\n\tProductProjection,\n\tProductTailoring,\n\tProductType,\n\tProject,\n\tQuote,\n\tQuoteRequest,\n\tRecurrencePolicy,\n\tRecurringOrder,\n\tReference,\n\tReferencedResourceNotFoundError,\n\tResourceIdentifier,\n\tShippingMethod,\n\tShoppingList,\n\tShoppingListLineItem,\n\tStagedQuote,\n\tState,\n\tStore,\n\tSubscription,\n\tTaxCategory,\n\tType,\n\tZone,\n} from \"@commercetools/platform-sdk\";\nimport { CommercetoolsError } from \"#src/exceptions.ts\";\nimport { cloneObject } from \"../helpers.ts\";\nimport { parseExpandClause } from \"../lib/expandParser.ts\";\nimport { parseQueryExpression } from \"../lib/predicateParser.ts\";\nimport type {\n\tPagedQueryResponseMap,\n\tResourceMap,\n\tResourceType,\n\tWritable,\n} from \"../types.ts\";\nimport type { GetParams, ProjectStorage, QueryParams } from \"./abstract.ts\";\nimport { AbstractStorage } from \"./abstract.ts\";\n\nexport class InMemoryStorage extends AbstractStorage {\n\tprotected resources: {\n\t\t[projectKey: string]: ProjectStorage;\n\t} = {};\n\n\tprotected projects: {\n\t\t[projectKey: string]: Project;\n\t} = {};\n\n\taddProject = (projectKey: string): Project => {\n\t\tif (!this.projects[projectKey]) {\n\t\t\tthis.projects[projectKey] = {\n\t\t\t\tkey: projectKey,\n\t\t\t\tname: \"\",\n\t\t\t\tcountries: [],\n\t\t\t\tcurrencies: [],\n\t\t\t\tlanguages: [],\n\t\t\t\tcreatedAt: \"2018-10-04T11:32:12.603Z\",\n\t\t\t\ttrialUntil: \"2018-12\",\n\t\t\t\tcarts: {\n\t\t\t\t\tcountryTaxRateFallbackEnabled: false,\n\t\t\t\t\tdeleteDaysAfterLastModification: 90,\n\t\t\t\t\tpriceRoundingMode: \"HalfEven\",\n\t\t\t\t\ttaxRoundingMode: \"HalfEven\",\n\t\t\t\t},\n\t\t\t\tshoppingLists: {\n\t\t\t\t\tdeleteDaysAfterLastModification: 360,\n\t\t\t\t},\n\t\t\t\tmessages: { enabled: false, deleteDaysAfterCreation: 15 },\n\t\t\t\tshippingRateInputType: undefined,\n\t\t\t\texternalOAuth: undefined,\n\t\t\t\tsearchIndexing: {\n\t\t\t\t\tproducts: {\n\t\t\t\t\t\tstatus: \"Deactivated\",\n\t\t\t\t\t},\n\t\t\t\t\tproductsSearch: {\n\t\t\t\t\t\tstatus: \"Deactivated\",\n\t\t\t\t\t},\n\t\t\t\t\torders: {\n\t\t\t\t\t\tstatus: \"Deactivated\",\n\t\t\t\t\t},\n\t\t\t\t\tcustomers: {\n\t\t\t\t\t\tstatus: \"Deactivated\",\n\t\t\t\t\t},\n\t\t\t\t\tbusinessUnits: {\n\t\t\t\t\t\tstatus: \"Deactivated\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tversion: 1,\n\t\t\t};\n\t\t}\n\t\treturn this.projects[projectKey];\n\t};\n\n\tsaveProject = (project: Project): Project => {\n\t\tthis.projects[project.key] = project;\n\t\treturn project;\n\t};\n\n\tgetProject = (projectKey: string): Project => this.addProject(projectKey);\n\n\t// Expand resolves a nested reference and injects the object in the given obj\n\tpublic expand = <T>(\n\t\tprojectKey: string,\n\t\tobj: T,\n\t\tclause: undefined | string | string[],\n\t): T => {\n\t\tif (!clause) return obj;\n\t\tconst newObj = cloneObject(obj);\n\t\tif (Array.isArray(clause)) {\n\t\t\tfor (const c of clause) {\n\t\t\t\tthis._resolveResource(projectKey, newObj, c);\n\t\t\t}\n\t\t} else {\n\t\t\tthis._resolveResource(projectKey, newObj, clause);\n\t\t}\n\t\treturn newObj;\n\t};\n\n\tprivate _resolveResource = (projectKey: string, obj: any, expand: string) => {\n\t\tconst params = parseExpandClause(expand);\n\n\t\t// 'lineItems[*].variant' on ShoppingList is an exception, these variants are not references\n\t\tif (params.index === \"*\") {\n\t\t\tconst reference = obj[params.element];\n\t\t\tif (\n\t\t\t\tparams.element === \"lineItems\" &&\n\t\t\t\tparams.rest?.startsWith(\"variant\") &&\n\t\t\t\treference.every(\n\t\t\t\t\t(item: any) =>\n\t\t\t\t\t\titem.variant === undefined && item.variantId !== undefined,\n\t\t\t\t)\n\t\t\t) {\n\t\t\t\tfor (const item of reference as ShoppingListLineItem[]) {\n\t\t\t\t\tthis._resolveShoppingListLineItemVariant(projectKey, item);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (!params.index) {\n\t\t\tconst reference = obj[params.element];\n\t\t\tif (reference === undefined) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis._resolveReference(projectKey, reference, params.rest);\n\t\t} else if (params.index === \"*\") {\n\t\t\tconst reference = obj[params.element];\n\t\t\tif (reference === undefined || !Array.isArray(reference)) return;\n\t\t\tfor (const itemRef of reference as Writable<Reference>[]) {\n\t\t\t\tthis._resolveReference(projectKey, itemRef, params.rest);\n\t\t\t}\n\t\t} else {\n\t\t\tconst reference = obj[params.element][params.index];\n\t\t\tif (reference === undefined) return;\n\t\t\tthis._resolveReference(projectKey, reference, params.rest);\n\t\t}\n\t};\n\n\tprivate forProjectKey(projectKey: string): ProjectStorage {\n\t\tthis.addProject(projectKey);\n\n\t\tlet projectStorage = this.resources[projectKey];\n\t\tif (!projectStorage) {\n\t\t\tprojectStorage = this.resources[projectKey] = {\n\t\t\t\t\"associate-role\": new Map<string, AssociateRole>(),\n\t\t\t\t\"attribute-group\": new Map<string, AttributeGroup>(),\n\t\t\t\t\"business-unit\": new Map<string, BusinessUnit>(),\n\t\t\t\tcart: new Map<string, Cart>(),\n\t\t\t\t\"cart-discount\": new Map<string, CartDiscount>(),\n\t\t\t\tcategory: new Map<string, Category>(),\n\t\t\t\tchannel: new Map<string, Channel>(),\n\t\t\t\tcustomer: new Map<string, Customer>(),\n\t\t\t\t\"customer-group\": new Map<string, CustomerGroup>(),\n\t\t\t\t\"discount-code\": new Map<string, DiscountCode>(),\n\t\t\t\t\"discount-group\": new Map<string, DiscountGroup>(),\n\t\t\t\textension: new Map<string, Extension>(),\n\t\t\t\t\"inventory-entry\": new Map<string, InventoryEntry>(),\n\t\t\t\t\"key-value-document\": new Map<string, CustomObject>(),\n\t\t\t\torder: new Map<string, Order>(),\n\t\t\t\t\"order-edit\": new Map<string, any>(),\n\t\t\t\tpayment: new Map<string, Payment>(),\n\t\t\t\tproduct: new Map<string, Product>(),\n\t\t\t\tquote: new Map<string, Quote>(),\n\t\t\t\t\"quote-request\": new Map<string, QuoteRequest>(),\n\t\t\t\t\"product-discount\": new Map<string, ProductDiscount>(),\n\t\t\t\t\"product-selection\": new Map<string, any>(),\n\t\t\t\t\"product-type\": new Map<string, ProductType>(),\n\t\t\t\t\"product-projection\": new Map<string, ProductProjection>(),\n\t\t\t\t\"product-tailoring\": new Map<string, ProductTailoring>(),\n\t\t\t\t\"recurrence-policy\": new Map<string, RecurrencePolicy>(),\n\t\t\t\t\"recurring-order\": new Map<string, RecurringOrder>(),\n\t\t\t\treview: new Map<string, any>(),\n\t\t\t\t\"shipping-method\": new Map<string, ShippingMethod>(),\n\t\t\t\t\"staged-quote\": new Map<string, StagedQuote>(),\n\t\t\t\tstate: new Map<string, State>(),\n\t\t\t\tstore: new Map<string, Store>(),\n\t\t\t\t\"shopping-list\": new Map<string, ShoppingList>(),\n\t\t\t\t\"standalone-price\": new Map<string, any>(),\n\t\t\t\tsubscription: new Map<string, Subscription>(),\n\t\t\t\t\"tax-category\": new Map<string, TaxCategory>(),\n\t\t\t\ttype: new Map<string, Type>(),\n\t\t\t\tzone: new Map<string, Zone>(),\n\t\t\t};\n\t\t}\n\t\treturn projectStorage;\n\t}\n\n\tclear() {\n\t\tfor (const [, projectStorage] of Object.entries(this.resources)) {\n\t\t\tfor (const [, value] of Object.entries(projectStorage)) {\n\t\t\t\tvalue?.clear();\n\t\t\t}\n\t\t}\n\t}\n\n\tall<RT extends ResourceType>(\n\t\tprojectKey: string,\n\t\ttypeId: RT,\n\t): ResourceMap[RT][] {\n\t\tconst store = this.forProjectKey(projectKey)[typeId];\n\t\tif (store) {\n\t\t\treturn Array.from(store.values()).map(cloneObject) as ResourceMap[RT][];\n\t\t}\n\t\treturn [];\n\t}\n\n\tadd<RT extends ResourceType>(\n\t\tprojectKey: string,\n\t\ttypeId: RT,\n\t\tobj: ResourceMap[RT],\n\t\tparams: GetParams = {},\n\t): ResourceMap[RT] {\n\t\tconst store = this.forProjectKey(projectKey);\n\t\tstore[typeId]?.set(obj.id, obj);\n\n\t\tconst resource = this.get(projectKey, typeId, obj.id, params);\n\t\tassert(\n\t\t\tresource,\n\t\t\t`resource of type ${typeId} with id ${obj.id} not created`,\n\t\t);\n\t\treturn cloneObject(resource);\n\t}\n\n\tget<RT extends ResourceType>(\n\t\tprojectKey: string,\n\t\ttypeId: RT,\n\t\tid: string,\n\t\tparams: GetParams = {},\n\t): ResourceMap[RT] | null {\n\t\tconst resource = this.forProjectKey(projectKey)[typeId]?.get(id);\n\t\tif (resource) {\n\t\t\tconst clone = cloneObject(resource);\n\t\t\treturn this.expand(projectKey, clone, params.expand) as ResourceMap[RT];\n\t\t}\n\t\treturn null;\n\t}\n\n\tgetByKey<RT extends ResourceType>(\n\t\tprojectKey: string,\n\t\ttypeId: RT,\n\t\tkey: string,\n\t\tparams: GetParams = {},\n\t): ResourceMap[RT] | null {\n\t\tconst store = this.forProjectKey(projectKey);\n\t\tconst resourceStore = store[typeId];\n\t\tif (!store) {\n\t\t\tthrow new Error(\"No type\");\n\t\t}\n\n\t\tconst resources: any[] = Array.from(resourceStore.values());\n\t\tconst resource = resources.find((e) => e.key === key);\n\t\tif (resource) {\n\t\t\tconst clone = cloneObject(resource);\n\t\t\treturn this.expand(projectKey, clone, params.expand) as ResourceMap[RT];\n\t\t}\n\t\treturn null;\n\t}\n\n\tdelete<RT extends ResourceType>(\n\t\tprojectKey: string,\n\t\ttypeId: RT,\n\t\tid: string,\n\t\tparams: GetParams = {},\n\t): ResourceMap[RT] | null {\n\t\tconst resource = this.get(projectKey, typeId, id);\n\n\t\tif (resource) {\n\t\t\tthis.forProjectKey(projectKey)[typeId]?.delete(id);\n\t\t\treturn this.expand(projectKey, resource, params.expand);\n\t\t}\n\t\treturn resource;\n\t}\n\n\tquery<RT extends ResourceType>(\n\t\tprojectKey: string,\n\t\ttypeId: RT,\n\t\tparams: QueryParams,\n\t): PagedQueryResponseMap[RT] {\n\t\tconst store = this.forProjectKey(projectKey)[typeId];\n\t\tif (!store) {\n\t\t\tthrow new Error(\"No type\");\n\t\t}\n\n\t\tlet resources = this.all<RT>(projectKey, typeId);\n\n\t\t// Apply predicates\n\t\tif (params.where) {\n\t\t\t// Get all key-value pairs starting with 'var.' to pass as variables, removing\n\t\t\t// the 'var.' prefix.\n\t\t\tconst vars = Object.fromEntries(\n\t\t\t\tObject.entries(params)\n\t\t\t\t\t.filter(([key]) => key.startsWith(\"var.\"))\n\t\t\t\t\t.map(([key, value]) => [key.slice(4), value]),\n\t\t\t);\n\n\t\t\ttry {\n\t\t\t\tconst filterFunc = parseQueryExpression(params.where);\n\t\t\t\tresources = resources.filter((resource) => filterFunc(resource, vars));\n\t\t\t} catch (err) {\n\t\t\t\tthrow new CommercetoolsError<InvalidInputError>(\n\t\t\t\t\t{\n\t\t\t\t\t\tcode: \"InvalidInput\",\n\t\t\t\t\t\tmessage: (err as any).message,\n\t\t\t\t\t},\n\t\t\t\t\t400,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\t// Get the total before slicing the array\n\t\tconst totalResources = resources.length;\n\n\t\t// Apply offset, limit\n\t\tconst offset = params.offset || 0;\n\t\tconst limit = params.limit || 20;\n\t\tresources = resources.slice(offset, offset + limit);\n\n\t\t// Expand the resources\n\t\tif (params.expand !== undefined) {\n\t\t\tresources = resources.map((resource) =>\n\t\t\t\tthis.expand(projectKey, resource, params.expand),\n\t\t\t);\n\t\t}\n\n\t\treturn {\n\t\t\tcount: totalResources,\n\t\t\ttotal: resources.length,\n\t\t\toffset: offset,\n\t\t\tlimit: limit,\n\t\t\tresults: resources.map(cloneObject),\n\t\t} as PagedQueryResponseMap[RT];\n\t}\n\n\tsearch(\n\t\tprojectKey: string,\n\t\ttypeId: ResourceType,\n\t\tparams: QueryParams,\n\t): PagedQueryResponse {\n\t\tlet resources = this.all(projectKey, typeId);\n\n\t\t// Apply predicates\n\t\tif (params.where) {\n\t\t\ttry {\n\t\t\t\tconst filterFunc = parseQueryExpression(params.where);\n\t\t\t\tresources = resources.filter((resource) => filterFunc(resource, {}));\n\t\t\t} catch (err) {\n\t\t\t\tthrow new CommercetoolsError<InvalidInputError>(\n\t\t\t\t\t{\n\t\t\t\t\t\tcode: \"InvalidInput\",\n\t\t\t\t\t\tmessage: (err as any).message,\n\t\t\t\t\t},\n\t\t\t\t\t400,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\t// Get the total before slicing the array\n\t\tconst totalResources = resources.length;\n\n\t\t// Apply offset, limit\n\t\tconst offset = params.offset || 0;\n\t\tconst limit = params.limit || 20;\n\t\tresources = resources.slice(offset, offset + limit);\n\n\t\t// Expand the resources\n\t\tif (params.expand !== undefined) {\n\t\t\tresources = resources.map((resource) =>\n\t\t\t\tthis.expand(projectKey, resource, params.expand),\n\t\t\t);\n\t\t}\n\n\t\treturn {\n\t\t\tcount: totalResources,\n\t\t\ttotal: resources.length,\n\t\t\toffset: offset,\n\t\t\tlimit: limit,\n\t\t\tresults: resources,\n\t\t};\n\t}\n\n\tgetByResourceIdentifier<RT extends ResourceType>(\n\t\tprojectKey: string,\n\t\tidentifier: ResourceIdentifier,\n\t): ResourceMap[RT] {\n\t\tif (identifier.id) {\n\t\t\tconst resource = this.get(projectKey, identifier.typeId, identifier.id);\n\t\t\tif (resource) {\n\t\t\t\treturn resource as ResourceMap[RT];\n\t\t\t}\n\n\t\t\tthrow new CommercetoolsError<ReferencedResourceNotFoundError>({\n\t\t\t\tcode: \"ReferencedResourceNotFound\",\n\t\t\t\tmessage: `The referenced object of type '${identifier.typeId}' with id '${identifier.id}' was not found. It either doesn't exist, or it can't be accessed from this endpoint (e.g., if the endpoint filters by store or customer account).`,\n\t\t\t\ttypeId: identifier.typeId,\n\t\t\t\tid: identifier.id,\n\t\t\t});\n\t\t}\n\n\t\tif (identifier.key) {\n\t\t\tconst resource = this.getByKey(\n\t\t\t\tprojectKey,\n\t\t\t\tidentifier.typeId,\n\t\t\t\tidentifier.key,\n\t\t\t);\n\t\t\tif (resource) {\n\t\t\t\treturn resource as ResourceMap[RT];\n\t\t\t}\n\n\t\t\tthrow new CommercetoolsError<ReferencedResourceNotFoundError>({\n\t\t\t\tcode: \"ReferencedResourceNotFound\",\n\t\t\t\tmessage: `The referenced object of type '${identifier.typeId}' with key '${identifier.key}' was not found. It either doesn't exist, or it can't be accessed from this endpoint (e.g., if the endpoint filters by store or customer account).`,\n\t\t\t\ttypeId: identifier.typeId,\n\t\t\t\tkey: identifier.key,\n\t\t\t});\n\t\t}\n\t\tthrow new CommercetoolsError<InvalidJsonInputError>({\n\t\t\tcode: \"InvalidJsonInput\",\n\t\t\tmessage: \"Request body does not contain valid JSON.\",\n\t\t\tdetailedErrorMessage: \"ResourceIdentifier requires an 'id' xor a 'key'\",\n\t\t});\n\t}\n\n\tprivate _resolveReference(\n\t\tprojectKey: string,\n\t\treference: any,\n\t\texpand: string | undefined,\n\t) {\n\t\tif (reference === undefined) return;\n\n\t\tif (\n\t\t\treference.typeId !== undefined &&\n\t\t\t(reference.id !== undefined || reference.key !== undefined)\n\t\t) {\n\t\t\t// First check if the object is already resolved. This is the case when\n\t\t\t// the complete resource is pushed via the .add() method.\n\t\t\tif (!reference.obj) {\n\t\t\t\treference.obj = this.getByResourceIdentifier(projectKey, {\n\t\t\t\t\ttypeId: reference.typeId,\n\t\t\t\t\tid: reference.id,\n\t\t\t\t\tkey: reference.key,\n\t\t\t\t} as ResourceIdentifier);\n\t\t\t}\n\t\t\tif (expand) {\n\t\t\t\tthis._resolveResource(projectKey, reference.obj, expand);\n\t\t\t}\n\t\t} else {\n\t\t\tif (expand) {\n\t\t\t\tthis._resolveResource(projectKey, reference, expand);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate _resolveShoppingListLineItemVariant(\n\t\tprojectKey: string,\n\t\tlineItem: ShoppingListLineItem,\n\t) {\n\t\tconst product = this.getByResourceIdentifier(projectKey, {\n\t\t\ttypeId: \"product\",\n\t\t\tid: lineItem.productId,\n\t\t}) as Product | undefined;\n\n\t\tif (!product) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst variant = [\n\t\t\tproduct.masterData.current.masterVariant,\n\t\t\t...product.masterData.current.variants,\n\t\t].find((e) => e.id === lineItem.variantId);\n\t\t// @ts-expect-error\n\t\tlineItem.variant = variant;\n\t}\n}\n","import type { NextFunction, Request, Response } from \"express\";\nimport express from \"express\";\nimport inject from \"light-my-request\";\nimport morgan from \"morgan\";\nimport { HttpResponse, http } from \"msw\";\nimport type { SetupServer, SetupServerApi } from \"msw/node\";\nimport { setupServer } from \"msw/node\";\nimport type { Config } from \"./config.ts\";\nimport { DEFAULT_API_HOSTNAME, DEFAULT_AUTH_HOSTNAME } from \"./constants.ts\";\nimport { CommercetoolsError } from \"./exceptions.ts\";\nimport { mapHeaderType } from \"./helpers.ts\";\nimport { copyHeaders } from \"./lib/proxy.ts\";\nimport { OAuth2Server } from \"./oauth/server.ts\";\nimport { ProjectAPI } from \"./projectAPI.ts\";\nimport type { RepositoryMap } from \"./repositories/index.ts\";\nimport { createRepositories } from \"./repositories/index.ts\";\nimport type { ProjectRepository } from \"./repositories/project.ts\";\nimport { createServices } from \"./services/index.ts\";\nimport { ProjectService } from \"./services/project.ts\";\nimport type { AbstractStorage } from \"./storage/index.ts\";\nimport { InMemoryStorage } from \"./storage/index.ts\";\n\nexport type CommercetoolsMockOptions = {\n\tvalidateCredentials: boolean;\n\tenableAuthentication: boolean;\n\tdefaultProjectKey: string | undefined;\n\tapiHost: RegExp | string;\n\tauthHost: RegExp | string;\n\tsilent: boolean;\n\tstrict: boolean;\n};\n\ntype AppOptions = { silent?: boolean };\n\nconst DEFAULT_OPTIONS: CommercetoolsMockOptions = {\n\tenableAuthentication: false,\n\tvalidateCredentials: false,\n\tdefaultProjectKey: undefined,\n\tapiHost: DEFAULT_API_HOSTNAME,\n\tauthHost: DEFAULT_AUTH_HOSTNAME,\n\tsilent: true,\n\tstrict: false,\n};\n\nconst _globalListeners: SetupServer[] = [];\n\nexport class CommercetoolsMock {\n\tpublic app: express.Express;\n\n\tpublic options: CommercetoolsMockOptions;\n\n\tprivate _storage: AbstractStorage;\n\n\tprivate _oauth2: OAuth2Server;\n\n\tprivate _mswServer: SetupServer | undefined = undefined;\n\n\tprivate _repositories: RepositoryMap | null;\n\n\t// biome-ignore lint: lint/correctness/noUnusedPrivateClassMembers\n\tprivate _projectService: ProjectService | undefined;\n\n\tconstructor(options: Partial<CommercetoolsMockOptions> = {}) {\n\t\tthis.options = { ...DEFAULT_OPTIONS, ...options };\n\t\tthis._repositories = null;\n\t\tthis._projectService = undefined;\n\n\t\tthis._storage = new InMemoryStorage();\n\t\tthis._oauth2 = new OAuth2Server({\n\t\t\tenabled: this.options.enableAuthentication,\n\t\t\tvalidate: this.options.validateCredentials,\n\t\t});\n\n\t\tthis.app = this.createApp({ silent: this.options.silent });\n\t}\n\n\tstart() {\n\t\tprocess.emitWarning(\n\t\t\t\"The start() method is deprecated, use .registerHandlers() to bind to an msw server instead\",\n\t\t\t\"DeprecationWarning\",\n\t\t);\n\n\t\t// Order is important here when the hostnames match\n\t\tthis.clear();\n\t\tthis.startServer();\n\t}\n\n\tstop() {\n\t\tprocess.emitWarning(\n\t\t\t\"The stop() method is deprecated, use .registerHandlers() to bind to an msw server instead\",\n\t\t\t\"DeprecationWarning\",\n\t\t);\n\t\tthis._mswServer?.close();\n\t\tthis._mswServer = undefined;\n\t}\n\n\tclear() {\n\t\tthis._storage.clear();\n\t}\n\n\tproject(projectKey?: string) {\n\t\tif (!projectKey && !this.options.defaultProjectKey) {\n\t\t\tthrow new Error(\"No projectKey passed and no default set\");\n\t\t}\n\n\t\tif (this._repositories === null) {\n\t\t\tthrow new Error(\"repositories not initialized yet\");\n\t\t}\n\n\t\tconst config: Config = {\n\t\t\tstrict: this.options.strict,\n\t\t\tstorage: this._storage,\n\t\t};\n\n\t\treturn new ProjectAPI(\n\t\t\tprojectKey || this.options.defaultProjectKey!,\n\t\t\tthis._repositories,\n\t\t\tconfig,\n\t\t);\n\t}\n\n\tauthStore() {\n\t\treturn this._oauth2.store;\n\t}\n\n\trunServer(port = 3000, options?: AppOptions) {\n\t\tconst server = this.app.listen(port, () => {});\n\t\tserver.keepAliveTimeout = 60 * 1000;\n\t}\n\n\tprivate createApp(options?: AppOptions): express.Express {\n\t\tconst config: Config = {\n\t\t\tstrict: this.options.strict,\n\t\t\tstorage: this._storage,\n\t\t};\n\t\tthis._repositories = createRepositories(config);\n\t\tthis._oauth2.setCustomerRepository(this._repositories.customer);\n\n\t\tconst app = express();\n\t\t// Set limit to 16mb, this is the maximum size allowed by the commercetools API: https://docs.commercetools.com/api/limits\n\t\tapp.use(express.json({ limit: \"16mb\" }));\n\n\t\tconst projectRouter = express.Router({ mergeParams: true });\n\n\t\tif (!options?.silent) {\n\t\t\tapp.use(morgan(\"tiny\"));\n\t\t}\n\t\tapp.use(\"/oauth\", this._oauth2.createRouter());\n\n\t\t// Only enable auth middleware if we have enabled this\n\t\tif (this.options.enableAuthentication) {\n\t\t\tapp.use(\"/:projectKey\", this._oauth2.createMiddleware(), projectRouter);\n\t\t\tapp.use(\n\t\t\t\t\"/:projectKey/in-store/key=:storeKey\",\n\t\t\t\tthis._oauth2.createMiddleware(),\n\t\t\t\tprojectRouter,\n\t\t\t);\n\t\t} else {\n\t\t\tapp.use(\"/:projectKey\", projectRouter);\n\t\t\tapp.use(\"/:projectKey/in-store/key=:storeKey\", projectRouter);\n\t\t}\n\n\t\t// Register the rest api services in the router\n\t\tcreateServices(projectRouter, this._repositories);\n\t\tthis._projectService = new ProjectService(\n\t\t\tprojectRouter,\n\t\t\tthis._repositories.project as ProjectRepository,\n\t\t);\n\n\t\tapp.use((err: Error, req: Request, resp: Response, next: NextFunction) => {\n\t\t\tif (err instanceof CommercetoolsError) {\n\t\t\t\tif (err.errors?.length > 0) {\n\t\t\t\t\tresp.status(err.statusCode).send({\n\t\t\t\t\t\tstatusCode: err.statusCode,\n\t\t\t\t\t\tmessage: err.message,\n\t\t\t\t\t\terrors: err.errors,\n\t\t\t\t\t});\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tresp.status(err.statusCode).send({\n\t\t\t\t\tstatusCode: err.statusCode,\n\t\t\t\t\tmessage: err.message,\n\t\t\t\t\terrors: [err.info],\n\t\t\t\t});\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tresp.status(500).send({\n\t\t\t\terror: err.message,\n\t\t\t});\n\t\t\treturn;\n\t\t});\n\n\t\treturn app;\n\t}\n\n\t// registerHandlers is an alternative way to work with commercetools-mock, it\n\t// allows you to manage msw server yourself and register the handlers needed\n\t// for commercetools-mock to work.\n\tpublic registerHandlers(server: SetupServerApi) {\n\t\tconst handlers = this.getHandlers();\n\t\tserver.use(...handlers);\n\t}\n\n\tpublic getHandlers() {\n\t\tconst app = this.app;\n\t\treturn [\n\t\t\thttp.post(`${this.options.authHost}/oauth/*`, async ({ request }) => {\n\t\t\t\tconst body = await request.text();\n\t\t\t\tconst url = new URL(request.url);\n\t\t\t\tconst headers = copyHeaders(request.headers);\n\n\t\t\t\tconst res = await inject(app)\n\t\t\t\t\t.post(`${url.pathname}?${url.searchParams.toString()}`)\n\t\t\t\t\t.body(body)\n\t\t\t\t\t.headers(headers)\n\t\t\t\t\t.end();\n\t\t\t\treturn new HttpResponse(res.body, {\n\t\t\t\t\tstatus: res.statusCode,\n\t\t\t\t\theaders: mapHeaderType(res.headers),\n\t\t\t\t});\n\t\t\t}),\n\t\t\thttp.head(`${this.options.apiHost}/*`, async ({ request }) => {\n\t\t\t\tconst body = await request.text();\n\t\t\t\tconst url = new URL(request.url);\n\t\t\t\tconst headers = copyHeaders(request.headers);\n\n\t\t\t\tconst res = await inject(app)\n\t\t\t\t\t.get(`${url.pathname}?${url.searchParams.toString()}`)\n\t\t\t\t\t.body(body)\n\t\t\t\t\t.headers(headers)\n\t\t\t\t\t.end();\n\n\t\t\t\tif (res.statusCode === 200) {\n\t\t\t\t\tconst parsedBody = JSON.parse(res.body);\n\t\t\t\t\t// Check if we have a count property (e.g. for query-lookups)\n\t\t\t\t\t// or if we have a result object (e.g. for single lookups)\n\t\t\t\t\tconst resultCount =\n\t\t\t\t\t\t\"count\" in parsedBody\n\t\t\t\t\t\t\t? parsedBody.count\n\t\t\t\t\t\t\t: Object.keys(parsedBody).length;\n\n\t\t\t\t\treturn new HttpResponse(null, {\n\t\t\t\t\t\tstatus: resultCount > 0 ? 200 : 404,\n\t\t\t\t\t\theaders: mapHeaderType(res.headers),\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\treturn new HttpResponse(null, {\n\t\t\t\t\tstatus: res.statusCode,\n\t\t\t\t\theaders: mapHeaderType(res.headers),\n\t\t\t\t});\n\t\t\t}),\n\t\t\thttp.get(`${this.options.apiHost}/*`, async ({ request }) => {\n\t\t\t\tconst body = await request.text();\n\t\t\t\tconst url = new URL(request.url);\n\t\t\t\tconst headers = copyHeaders(request.headers);\n\n\t\t\t\tconst res = await inject(app)\n\t\t\t\t\t.get(`${url.pathname}?${url.searchParams.toString()}`)\n\t\t\t\t\t.body(body)\n\t\t\t\t\t.headers(headers)\n\t\t\t\t\t.end();\n\t\t\t\treturn new HttpResponse(res.body, {\n\t\t\t\t\tstatus: res.statusCode,\n\t\t\t\t\theaders: mapHeaderType(res.headers),\n\t\t\t\t});\n\t\t\t}),\n\t\t\thttp.post(`${this.options.apiHost}/*`, async ({ request }) => {\n\t\t\t\tconst body = await request.text();\n\t\t\t\tconst url = new URL(request.url);\n\t\t\t\tconst headers = copyHeaders(request.headers);\n\n\t\t\t\tconst res = await inject(app)\n\t\t\t\t\t.post(`${url.pathname}?${url.searchParams.toString()}`)\n\t\t\t\t\t.body(body)\n\t\t\t\t\t.headers(headers)\n\t\t\t\t\t.end();\n\t\t\t\treturn new HttpResponse(res.body, {\n\t\t\t\t\tstatus: res.statusCode,\n\t\t\t\t\theaders: mapHeaderType(res.headers),\n\t\t\t\t});\n\t\t\t}),\n\t\t\thttp.delete(`${this.options.apiHost}/*`, async ({ request }) => {\n\t\t\t\tconst body = await request.text();\n\t\t\t\tconst url = new URL(request.url);\n\t\t\t\tconst headers = copyHeaders(request.headers);\n\n\t\t\t\tconst res = await inject(app)\n\t\t\t\t\t.delete(`${url.pathname}?${url.searchParams.toString()}`)\n\t\t\t\t\t.body(body)\n\t\t\t\t\t.headers(headers)\n\t\t\t\t\t.end();\n\t\t\t\treturn new HttpResponse(res.body, {\n\t\t\t\t\tstatus: res.statusCode,\n\t\t\t\t\theaders: mapHeaderType(res.headers),\n\t\t\t\t});\n\t\t\t}),\n\t\t];\n\t}\n\n\tpublic mswServer() {\n\t\treturn this._mswServer;\n\t}\n\n\tprivate startServer() {\n\t\t// Check if there are any other servers running\n\t\tif (_globalListeners.length > 0) {\n\t\t\tif (this._mswServer !== undefined) {\n\t\t\t\tthrow new Error(\"Server already started\");\n\t\t\t}\n\t\t\tprocess.emitWarning(\"Server wasn't stopped properly, clearing\");\n\t\t\tfor (const listener of _globalListeners) {\n\t\t\t\tlistener.close();\n\t\t\t}\n\t\t\t_globalListeners.length = 0;\n\t\t}\n\n\t\tconst server = setupServer();\n\t\tthis.registerHandlers(server);\n\t\tserver.listen({\n\t\t\t// We need to allow requests done by supertest\n\t\t\tonUnhandledRequest: (request, print) => {\n\t\t\t\tconst url = new URL(request.url);\n\t\t\t\tif (url.hostname === \"127.0.0.1\") {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tprint.error();\n\t\t\t},\n\t\t});\n\t\t_globalListeners.push(server);\n\t\tthis._mswServer = server;\n\t}\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["uuidv4","values: string[]","headersInit: HeadersInit","result: Record<string, string>","uuidv4","token: Token","uuidv4","options: { enabled: boolean; validate: boolean }","_storage: AbstractStorage","uuidv4","a","taxedItemPrices: TaxedItemPrice[]","taxedShippingPrice: TaxedItemPrice | undefined","taxPortions: TaxPortion[]","netAmount: number","grossAmount: number","taxAmount: number","result: Record<number, ShippingRatePriceTier>","totalGross: CentPrecisionMoney","Decimal","totalNet: CentPrecisionMoney","taxPortions: TaxPortion[]","taxedPrice: TaxedItemPrice","taxCategory: TaxCategory | undefined","uuidv4","product: Product | null","variant: ProductVariant | undefined","uuidv4","lineItem: Writable<LineItem> | undefined","customLineItem","custom: CustomFields | undefined","storedBusinessUnit: BusinessUnit | undefined","resource: Writable<Cart>","product: Product | null","uuidv4","resolved: ReturnInfo","syncData: SyncInfo","resource: Writable<Order>","product: Product","variant: ProductVariant | undefined","cartLikeForMatching: Writable<Cart>","stateReference: StateReference | undefined","resource: QuoteRequest","resource: AssociateRole","resource: AttributeGroup","resource: CartDiscount","result: ExpandResult","uuidv4","resource: Category","uuidv4","node: Category","ancestors: CategoryReference[]","resource: Channel","resource: CustomObject","addresses: Address[]","addresses","storesForCustomer: StoreKeyReference[]","resource: Customer","updatedResource: Customer","stores: Store[]","resource: CustomerGroup","resource: DiscountCode","resource: DiscountGroup","resource: Extension","resource: InventoryEntry","resource: OrderEdit","uuidv4","updatedTransaction: Transaction","resource: Payment","_storage: AbstractStorage","ratingsDistribution: { [key: string]: number }","Token","e","fn: NudFunction<T> | undefined","generateMatchFunc","getLexer","parsed: any","expressions: RangeExpression[] | FilterExpression[] | TypeSymbol[]","expr: any","ranges: any","func: (obj: any) => boolean","isSearchAndExpression","isSearchOrExpression","isSearchNotExpression","isSearchFilterExpression","isSearchRangeExpression","isSearchExactExpression","isSearchExistsExpression","isSearchFullTextExpression","isSearchFullTextPrefixExpression","isSearchPrefixExpression","isSearchWildCardExpression","generateMatchFunc","variants: Writable<ProductVariant>[]","results: ProductSearchResult[]","uuidv4","priceToAdd","variantDraft: ProductVariantDraft","variant","existingAttr","price","taxCategoryReference: TaxCategoryReference | undefined","productStateReference: StateReference | undefined","productType: ProductTypeReference | undefined","categoryReferences: CategoryReference[]","taxCategoryReference: TaxCategoryReference | undefined","productStateReference: StateReference | undefined","productData: ProductData","resource: Product","resource: ProductDiscount","expr: any","value","result: FacetResults","result: Writable<TermFacetResult>","terms: Record<any, number>","values: number[]","variableMap: Record<string, QueryParam>","resource: ProductSelection","resource: ProductType","result: AttributeDefinition[]","stateReference: StateReference | undefined","stateReference: StateReference | undefined","resource: RecurrencePolicy","resource: RecurringOrder","resource: Review","resource: ShippingMethod","z","product: Product | null","varId: number | undefined","uuidv4","lineItem: Writable<ShoppingListLineItem> | undefined","resource: ShoppingList","lineItem: Writable<ShoppingListLineItem>","resource: StandalonePrice","resource: State","resource: Store","resource: Subscription","uuidv4","resource: TaxCategory","result: FieldDefinition[]","resource: Type","resource: Zone","err: any","params: QueryParams","cartOrOrder: Cart | Order | null","cartDraft: CartDraft","draft: CustomObjectDraft","result: CustomerSignInResult","searchParams: ProductProjectionQueryParams","DEFAULT_OPTIONS: CommercetoolsMockOptions","_globalListeners: SetupServer[]","config: Config"],"sources":["../src/constants.ts","../src/exceptions.ts","../src/helpers.ts","../src/lib/proxy.ts","../src/lib/password.ts","../src/oauth/helpers.ts","../src/oauth/store.ts","../src/oauth/server.ts","../src/projectAPI.ts","../src/repositories/errors.ts","../src/repositories/abstract.ts","../src/repositories/product-tailoring.ts","../src/repositories/helpers.ts","../src/lib/tax.ts","../src/shipping.ts","../src/repositories/cart/helpers.ts","../src/repositories/cart/actions.ts","../src/repositories/cart/index.ts","../src/repositories/order/actions.ts","../src/repositories/order/index.ts","../src/repositories/quote-request/actions.ts","../src/repositories/quote-request/index.ts","../src/repositories/as-associate.ts","../src/repositories/associate-role.ts","../src/repositories/attribute-group.ts","../src/repositories/business-unit.ts","../src/repositories/cart-discount/actions.ts","../src/repositories/cart-discount/index.ts","../src/lib/expandParser.ts","../src/repositories/category/actions.ts","../src/repositories/category/index.ts","../src/repositories/channel.ts","../src/repositories/custom-object.ts","../src/repositories/customer/actions.ts","../src/repositories/customer/index.ts","../src/repositories/customer-group.ts","../src/repositories/discount-code/actions.ts","../src/repositories/discount-code/index.ts","../src/repositories/discount-group/actions.ts","../src/repositories/discount-group/index.ts","../src/lib/masking.ts","../src/repositories/extension.ts","../src/repositories/inventory-entry/actions.ts","../src/repositories/inventory-entry/index.ts","../src/repositories/my-customer.ts","../src/repositories/my-order.ts","../src/repositories/order-edit.ts","../src/repositories/payment/helpers.ts","../src/repositories/payment/actions.ts","../src/repositories/payment/index.ts","../src/lib/review-statistics.ts","../vendor/perplex/lexer-state.ts","../vendor/perplex/token.ts","../vendor/perplex/token-types.ts","../vendor/perplex/lexer.ts","../vendor/pratt/index.ts","../src/lib/projectionSearchFilter.ts","../src/lib/productSearchFilter.ts","../src/lib/searchQueryTypeChecker.ts","../src/priceSelector.ts","../src/product-search.ts","../src/repositories/product/helpers.ts","../src/repositories/product/actions.ts","../src/repositories/product/index.ts","../src/repositories/product-discount.ts","../src/lib/haversine.ts","../src/lib/predicateParser.ts","../src/product-projection-search.ts","../src/repositories/product-projection.ts","../src/repositories/product-selection.ts","../src/repositories/product-type.ts","../src/repositories/project.ts","../src/repositories/quote/actions.ts","../src/repositories/quote/index.ts","../src/repositories/quote-staged/actions.ts","../src/repositories/quote-staged/index.ts","../src/repositories/recurrence-policy/actions.ts","../src/repositories/recurrence-policy/index.ts","../src/repositories/recurring-order/actions.ts","../src/repositories/recurring-order/index.ts","../src/repositories/review.ts","../src/repositories/shipping-method/helpers.ts","../src/repositories/shipping-method/actions.ts","../src/repositories/shipping-method/index.ts","../src/repositories/shopping-list/actions.ts","../src/repositories/shopping-list/index.ts","../src/repositories/standalone-price.ts","../src/repositories/state.ts","../src/repositories/store.ts","../src/repositories/subscription.ts","../src/repositories/tax-category/helpers.ts","../src/repositories/tax-category/actions.ts","../src/repositories/tax-category/index.ts","../src/repositories/type/actions.ts","../src/repositories/type/index.ts","../src/repositories/zone.ts","../src/repositories/index.ts","../src/schemas/update-request.ts","../src/validate.ts","../src/services/abstract.ts","../src/services/as-associate-cart.ts","../src/services/as-associate-order.ts","../src/services/as-associate-quote-request.ts","../src/services/as-associate.ts","../src/services/associate-roles.ts","../src/services/attribute-group.ts","../src/services/business-units.ts","../src/services/cart.ts","../src/services/cart-discount.ts","../src/services/category.ts","../src/services/channel.ts","../src/services/custom-object.ts","../src/services/customer.ts","../src/services/customer-group.ts","../src/services/discount-code.ts","../src/services/discount-group.ts","../src/services/extension.ts","../src/services/inventory-entry.ts","../src/services/my-business-unit.ts","../src/services/my-cart.ts","../src/services/my-customer.ts","../src/services/my-order.ts","../src/services/my-payment.ts","../src/services/my-shopping-list.ts","../src/services/order.ts","../src/services/payment.ts","../src/services/product.ts","../src/services/product-discount.ts","../src/services/product-projection.ts","../src/services/product-selection.ts","../src/services/product-type.ts","../src/services/quote.ts","../src/services/quote-request.ts","../src/services/quote-staged.ts","../src/services/recurrence-policy.ts","../src/services/recurring-order.ts","../src/services/reviews.ts","../src/services/shipping-method.ts","../src/services/shopping-list.ts","../src/services/standalone-price.ts","../src/services/state.ts","../src/services/store.ts","../src/services/subscription.ts","../src/services/tax-category.ts","../src/services/type.ts","../src/services/zone.ts","../src/services/index.ts","../src/services/project.ts","../src/storage/abstract.ts","../src/storage/in-memory.ts","../src/ctMock.ts"],"sourcesContent":["export const DEFAULT_API_HOSTNAME = \"https://api.*.commercetools.com\";\nexport const DEFAULT_AUTH_HOSTNAME = \"https://auth.*.commercetools.com\";\n","export abstract class BaseError {\n\tabstract message: string;\n\n\tabstract errors?: BaseError[];\n}\n\nexport class CommercetoolsError<T extends BaseError> extends Error {\n\tinfo: T;\n\n\tstatusCode: number;\n\n\terrors: BaseError[];\n\n\tconstructor(info: T, statusCode = 400) {\n\t\tsuper(info.message);\n\t\tthis.info = info;\n\t\tthis.statusCode = statusCode || 500;\n\t\tthis.errors = info.errors ?? [];\n\t}\n}\n\nexport interface InvalidRequestError {\n\treadonly code: \"invalid_request\";\n\treadonly message: string;\n}\n\nexport interface AuthError {\n\treadonly statusCode: number;\n\treadonly message: string;\n\treadonly error: string;\n\treadonly error_description: string;\n}\n","import type { OutgoingHttpHeaders } from \"node:http\";\nimport type { ParsedQs } from \"qs\";\nimport { v4 as uuidv4 } from \"uuid\";\n\nexport const getBaseResourceProperties = () => ({\n\tid: uuidv4(),\n\tcreatedAt: new Date().toISOString(),\n\tlastModifiedAt: new Date().toISOString(),\n\tversion: 0,\n});\n\n/**\n * Do a nested lookup by using a path. For example `foo.bar.value` will\n * return obj['foo']['bar']['value']\n */\nexport const nestedLookup = (obj: any, path: string): any => {\n\tif (!path || path === \"\") {\n\t\treturn obj;\n\t}\n\n\tconst parts = path.split(\".\");\n\tlet val = obj;\n\n\tfor (let i = 0; i < parts.length; i++) {\n\t\tconst part = parts[i];\n\t\tif (val === undefined) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tval = val[part];\n\t}\n\n\treturn val;\n};\n\nexport const queryParamsArray = (\n\tinput: string | ParsedQs | string[] | ParsedQs[] | undefined,\n): string[] | undefined => {\n\tif (input === undefined) {\n\t\treturn undefined;\n\t}\n\n\tconst values: string[] = Array.isArray(input)\n\t\t? (input as string[])\n\t\t: ([input] as string[]);\n\tif (values.length < 1) {\n\t\treturn undefined;\n\t}\n\treturn values;\n};\n\nexport const queryParamsValue = (\n\tvalue: string | ParsedQs | string[] | ParsedQs[] | undefined,\n): string | undefined => {\n\tconst values = queryParamsArray(value);\n\tif (values && values.length > 0) {\n\t\treturn values[0];\n\t}\n\treturn undefined;\n};\n\nexport const cloneObject = <T>(o: T): T => JSON.parse(JSON.stringify(o));\n\nexport const mapHeaderType = (\n\toutgoingHttpHeaders: OutgoingHttpHeaders,\n): HeadersInit => {\n\tconst headersInit: HeadersInit = {};\n\tfor (const key in outgoingHttpHeaders) {\n\t\tconst value = outgoingHttpHeaders[key];\n\t\tif (Array.isArray(value)) {\n\t\t\t// Join multiple values for the same header with a comma\n\t\t\theadersInit[key] = value.join(\", \");\n\t\t} else if (value !== undefined) {\n\t\t\t// Single value or undefined\n\t\t\theadersInit[key] = value.toString();\n\t\t}\n\t}\n\treturn headersInit;\n};\n\nexport const generateRandomString = (length: number) => {\n\tconst characters =\n\t\t\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\";\n\tlet result = \"\";\n\tfor (let i = 0; i < length; i++) {\n\t\tconst randomIndex = Math.floor(Math.random() * characters.length);\n\t\tresult += characters[randomIndex];\n\t}\n\treturn result;\n};\n","export const copyHeaders = (headers: Headers) => {\n\tconst validHeaders = [\"accept\", \"host\", \"authorization\", \"content-type\"];\n\tconst result: Record<string, string> = {};\n\n\tfor (const [key, value] of headers.entries()) {\n\t\tif (validHeaders.includes(key.toLowerCase())) {\n\t\t\tresult[key] = value;\n\t\t}\n\t}\n\n\treturn result;\n};\n","import type { Customer } from \"@commercetools/platform-sdk\";\nimport { v4 as uuidv4 } from \"uuid\";\n\nconst PWRESET_SECRET = \"pwreset\";\nconst EMAIL_VERIFY_SECRET = \"emailverifysecret\";\n\nexport const validatePassword = (\n\tclearPassword: string,\n\thashedPassword: string,\n) => hashPassword(clearPassword) === hashedPassword;\n\nexport const hashPassword = (clearPassword: string) =>\n\tBuffer.from(clearPassword).toString(\"base64\");\n\nexport const createPasswordResetToken = (customer: Customer, expiresAt: Date) =>\n\tBuffer.from(\n\t\t`${customer.id}:${PWRESET_SECRET}:${expiresAt.getTime()}`,\n\t).toString(\"base64\");\n\nexport const createEmailVerifyToken = (customer: Customer) =>\n\tBuffer.from(`${customer.id}:${EMAIL_VERIFY_SECRET}:${uuidv4()}`).toString(\n\t\t\"base64\",\n\t);\n\nexport const validatePasswordResetToken = (token: string) => {\n\tconst items = Buffer.from(token, \"base64\").toString(\"utf-8\").split(\":\");\n\tconst [customerId, secret, time] = items;\n\n\tif (secret !== PWRESET_SECRET) {\n\t\treturn undefined;\n\t}\n\n\t// Check if the token is expired\n\tif (Number.parseInt(time, 10) < Date.now()) {\n\t\treturn undefined;\n\t}\n\n\treturn customerId;\n};\n\nexport const validateEmailVerifyToken = (token: string) => {\n\tconst items = Buffer.from(token, \"base64\").toString(\"utf-8\").split(\":\");\n\tconst [customerId, secret] = items;\n\tif (secret !== EMAIL_VERIFY_SECRET) {\n\t\treturn undefined;\n\t}\n\n\treturn customerId;\n};\n","import type { Request } from \"express\";\n\nexport const getBearerToken = (request: Request): string | undefined => {\n\tconst authHeader = request.header(\"Authorization\");\n\tconst match = authHeader?.match(/^Bearer\\s(?<token>[^\\s]+)$/);\n\tif (match) {\n\t\treturn match.groups?.token;\n\t}\n\treturn undefined;\n};\n","import { randomBytes } from \"node:crypto\";\nimport { v4 as uuidv4 } from \"uuid\";\n\ntype Token = {\n\taccess_token: string;\n\ttoken_type: \"Bearer\";\n\texpires_in: number;\n\tscope: string;\n\trefresh_token?: string;\n};\n\nexport class OAuth2Store {\n\ttokens: Token[] = [];\n\n\tvalidate = true;\n\n\tconstructor(validate = true) {\n\t\tthis.validate = validate;\n\t}\n\n\taddToken(token: Token) {\n\t\tthis.tokens.push(token);\n\t}\n\n\tgetClientToken(clientId: string, clientSecret: string, scope?: string) {\n\t\tconst token: Token = {\n\t\t\taccess_token: randomBytes(16).toString(\"base64\"),\n\t\t\ttoken_type: \"Bearer\",\n\t\t\texpires_in: 172800,\n\t\t\tscope: scope || \"todo\",\n\t\t\trefresh_token: `my-project-${randomBytes(16).toString(\"base64\")}`,\n\t\t};\n\t\tthis.addToken(token);\n\t\treturn token;\n\t}\n\n\tgetAnonymousToken(\n\t\tprojectKey: string,\n\t\tanonymousId: string | undefined,\n\t\tscope: string,\n\t) {\n\t\tif (!anonymousId) {\n\t\t\tanonymousId = uuidv4();\n\t\t}\n\t\tconst token: Token = {\n\t\t\taccess_token: randomBytes(16).toString(\"base64\"),\n\t\t\ttoken_type: \"Bearer\",\n\t\t\texpires_in: 172800,\n\t\t\tscope: scope\n\t\t\t\t? `${scope} anonymous_id:${anonymousId}`\n\t\t\t\t: `anonymous_id:${anonymousId}`,\n\t\t\trefresh_token: `${projectKey}:${randomBytes(16).toString(\"base64\")}`,\n\t\t};\n\t\tthis.addToken(token);\n\t\treturn token;\n\t}\n\n\tgetCustomerToken(projectKey: string, customerId: string, scope: string) {\n\t\tconst token: Token = {\n\t\t\taccess_token: randomBytes(16).toString(\"base64\"),\n\t\t\ttoken_type: \"Bearer\",\n\t\t\texpires_in: 172800,\n\t\t\tscope: scope\n\t\t\t\t? `${scope} customer_id:${customerId}`\n\t\t\t\t: `customer_id:${customerId}`,\n\t\t\trefresh_token: `${projectKey}:${randomBytes(16).toString(\"base64\")}`,\n\t\t};\n\t\tthis.addToken(token);\n\t\treturn token;\n\t}\n\n\trefreshToken(clientId: string, clientSecret: string, refreshToken: string) {\n\t\tconst existing = this.tokens.find((t) => t.refresh_token === refreshToken);\n\t\tif (!existing) {\n\t\t\treturn undefined;\n\t\t}\n\t\tconst token: Token = {\n\t\t\t...existing,\n\t\t\taccess_token: randomBytes(16).toString(\"base64\"),\n\t\t};\n\t\tthis.addToken(token);\n\n\t\t// We don't want to return the refresh_token again\n\t\treturn {\n\t\t\taccess_token: token.access_token,\n\t\t\ttoken_type: token.token_type,\n\t\t\texpires_in: token.expires_in,\n\t\t\tscope: token.scope,\n\t\t};\n\t}\n\n\tvalidateToken(token: string) {\n\t\tif (!this.validate) return true;\n\n\t\tconst foundToken = this.tokens.find((t) => t.access_token === token);\n\t\tif (foundToken) {\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n}\n","import type { InvalidTokenError } from \"@commercetools/platform-sdk\";\nimport auth from \"basic-auth\";\nimport bodyParser from \"body-parser\";\nimport express, {\n\ttype NextFunction,\n\ttype Request,\n\ttype Response,\n} from \"express\";\nimport type { AuthError, InvalidRequestError } from \"#src/exceptions.ts\";\nimport { CommercetoolsError } from \"#src/exceptions.ts\";\nimport { hashPassword } from \"../lib/password.ts\";\nimport type { CustomerRepository } from \"../repositories/customer/index.ts\";\nimport type { InvalidClientError, UnsupportedGrantType } from \"./errors.ts\";\nimport { getBearerToken } from \"./helpers.ts\";\nimport { OAuth2Store } from \"./store.ts\";\n\ntype AuthRequest = Request & {\n\tcredentials?: {\n\t\tclientId: string;\n\t\tclientSecret: string;\n\t};\n};\nexport type Token = {\n\taccess_token: string;\n\ttoken_type: \"Bearer\";\n\texpires_in: number;\n\tscope: string;\n\trefresh_token?: string;\n};\n\nexport class OAuth2Server {\n\tstore: OAuth2Store;\n\n\tprivate customerRepository: CustomerRepository;\n\n\tconstructor(private options: { enabled: boolean; validate: boolean }) {\n\t\tthis.store = new OAuth2Store(options.validate);\n\t}\n\n\tsetCustomerRepository(repository: CustomerRepository) {\n\t\tthis.customerRepository = repository;\n\t}\n\n\tcreateRouter() {\n\t\tconst router = express.Router();\n\t\trouter.use(bodyParser.urlencoded({ extended: true }));\n\t\trouter.use(this.validateClientCredentials.bind(this));\n\t\trouter.post(\"/token\", this.tokenHandler.bind(this));\n\t\trouter.post(\n\t\t\t\"/:projectKey/customers/token\",\n\t\t\tthis.customerTokenHandler.bind(this),\n\t\t);\n\t\trouter.post(\n\t\t\t\"/:projectKey/in-store/key=:storeKey/customers/token\",\n\t\t\tthis.inStoreCustomerTokenHandler.bind(this),\n\t\t);\n\t\trouter.post(\n\t\t\t\"/:projectKey/anonymous/token\",\n\t\t\tthis.anonymousTokenHandler.bind(this),\n\t\t);\n\t\treturn router;\n\t}\n\n\tcreateMiddleware() {\n\t\tif (!this.options.validate) {\n\t\t\treturn async (\n\t\t\t\trequest: Request,\n\t\t\t\tresponse: Response,\n\t\t\t\tnext: NextFunction,\n\t\t\t) => {\n\t\t\t\tnext();\n\t\t\t};\n\t\t}\n\n\t\treturn async (request: Request, response: Response, next: NextFunction) => {\n\t\t\tconst token = getBearerToken(request);\n\t\t\tif (!token) {\n\t\t\t\treturn next(\n\t\t\t\t\tnew CommercetoolsError<InvalidTokenError>(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcode: \"invalid_token\",\n\t\t\t\t\t\t\tmessage:\n\t\t\t\t\t\t\t\t\"This endpoint requires an access token. You can get one from the authorization server.\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\t401,\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tif (!token || !this.store.validateToken(token)) {\n\t\t\t\treturn next(\n\t\t\t\t\tnew CommercetoolsError<InvalidTokenError>(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcode: \"invalid_token\",\n\t\t\t\t\t\t\tmessage: \"invalid_token\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\t401,\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}\n\n\t\t\treturn next();\n\t\t};\n\t}\n\n\tasync validateClientCredentials(\n\t\trequest: AuthRequest,\n\t\tresponse: Response,\n\t\tnext: NextFunction,\n\t) {\n\t\tconst authHeader = request.header(\"Authorization\");\n\t\tif (!authHeader) {\n\t\t\treturn next(\n\t\t\t\tnew CommercetoolsError<InvalidClientError>(\n\t\t\t\t\t{\n\t\t\t\t\t\tcode: \"invalid_client\",\n\t\t\t\t\t\tmessage:\n\t\t\t\t\t\t\t\"Please provide valid client credentials using HTTP Basic Authentication.\",\n\t\t\t\t\t},\n\t\t\t\t\t401,\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\t\tconst credentials = auth.parse(authHeader);\n\t\tif (!credentials) {\n\t\t\treturn next(\n\t\t\t\tnew CommercetoolsError<InvalidClientError>(\n\t\t\t\t\t{\n\t\t\t\t\t\tcode: \"invalid_client\",\n\t\t\t\t\t\tmessage:\n\t\t\t\t\t\t\t\"Please provide valid client credentials using HTTP Basic Authentication.\",\n\t\t\t\t\t},\n\t\t\t\t\t400,\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\n\t\trequest.credentials = {\n\t\t\tclientId: credentials.name,\n\t\t\tclientSecret: credentials.pass,\n\t\t};\n\n\t\tnext();\n\t}\n\n\tasync tokenHandler(\n\t\trequest: AuthRequest,\n\t\tresponse: Response,\n\t\tnext: NextFunction,\n\t) {\n\t\tif (!request.credentials) {\n\t\t\treturn next(\n\t\t\t\tnew CommercetoolsError<InvalidClientError>(\n\t\t\t\t\t{\n\t\t\t\t\t\tcode: \"invalid_client\",\n\t\t\t\t\t\tmessage: \"Client credentials are missing.\",\n\t\t\t\t\t},\n\t\t\t\t\t401,\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\n\t\tconst grantType = request.query.grant_type || request.body?.grant_type;\n\t\tif (!grantType) {\n\t\t\treturn next(\n\t\t\t\tnew CommercetoolsError<InvalidRequestError>(\n\t\t\t\t\t{\n\t\t\t\t\t\tcode: \"invalid_request\",\n\t\t\t\t\t\tmessage: \"Missing required parameter: grant_type.\",\n\t\t\t\t\t},\n\t\t\t\t\t400,\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\n\t\tif (grantType === \"client_credentials\") {\n\t\t\tconst token = this.store.getClientToken(\n\t\t\t\trequest.credentials.clientId,\n\t\t\t\trequest.credentials.clientSecret,\n\t\t\t\trequest.query.scope?.toString(),\n\t\t\t);\n\t\t\tresponse.status(200).send(token);\n\t\t\treturn;\n\t\t}\n\t\tif (grantType === \"refresh_token\") {\n\t\t\tconst refreshToken =\n\t\t\t\trequest.query.refresh_token?.toString() || request.body?.refresh_token;\n\t\t\tif (!refreshToken) {\n\t\t\t\treturn next(\n\t\t\t\t\tnew CommercetoolsError<InvalidRequestError>(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcode: \"invalid_request\",\n\t\t\t\t\t\t\tmessage: \"Missing required parameter: refresh_token.\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\t400,\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst token = this.store.refreshToken(\n\t\t\t\trequest.credentials.clientId,\n\t\t\t\trequest.credentials.clientSecret,\n\t\t\t\trefreshToken,\n\t\t\t);\n\t\t\tif (!token) {\n\t\t\t\treturn next(\n\t\t\t\t\tnew CommercetoolsError<AuthError>(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tstatusCode: 400,\n\t\t\t\t\t\t\tmessage: \"The refresh token was not found. It may have expired.\",\n\t\t\t\t\t\t\terror: \"invalid_grant\",\n\t\t\t\t\t\t\terror_description:\n\t\t\t\t\t\t\t\t\"The refresh token was not found. It may have expired.\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\t400,\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}\n\t\t\tresponse.status(200).send(token);\n\t\t\treturn;\n\t\t}\n\t\treturn next(\n\t\t\tnew CommercetoolsError<UnsupportedGrantType>(\n\t\t\t\t{\n\t\t\t\t\tcode: \"unsupported_grant_type\",\n\t\t\t\t\tmessage: `Invalid parameter: grant_type: Invalid grant type: ${grantType}`,\n\t\t\t\t},\n\t\t\t\t400,\n\t\t\t),\n\t\t);\n\t}\n\n\tasync customerTokenHandler(\n\t\trequest: AuthRequest,\n\t\tresponse: Response,\n\t\tnext: NextFunction,\n\t) {\n\t\tconst projectKey = request.params.projectKey;\n\t\tconst grantType = request.query.grant_type || request.body?.grant_type;\n\t\tif (!grantType) {\n\t\t\treturn next(\n\t\t\t\tnew CommercetoolsError<InvalidRequestError>(\n\t\t\t\t\t{\n\t\t\t\t\t\tcode: \"invalid_request\",\n\t\t\t\t\t\tmessage: \"Missing required parameter: grant_type.\",\n\t\t\t\t\t},\n\t\t\t\t\t400,\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\n\t\tif (grantType === \"password\") {\n\t\t\tconst username = request.query.username || request.body?.username;\n\t\t\tconst password = hashPassword(\n\t\t\t\trequest.query.password || request.body.password,\n\t\t\t);\n\t\t\tconst scope =\n\t\t\t\trequest.query.scope?.toString() || request.body?.scope?.toString();\n\n\t\t\tconst result = this.customerRepository.query(\n\t\t\t\t{ projectKey: request.params.projectKey },\n\t\t\t\t{\n\t\t\t\t\twhere: [`email = \"${username}\"`, `password = \"${password}\"`],\n\t\t\t\t},\n\t\t\t);\n\n\t\t\tif (result.count === 0) {\n\t\t\t\treturn next(\n\t\t\t\t\tnew CommercetoolsError<any>(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcode: \"invalid_customer_account_credentials\",\n\t\t\t\t\t\t\tmessage: \"Customer account with the given credentials not found.\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\t400,\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst customer = result.results[0];\n\t\t\tconst token = this.store.getCustomerToken(projectKey, customer.id, scope);\n\t\t\tresponse.status(200).send(token);\n\t\t}\n\t}\n\n\tasync inStoreCustomerTokenHandler(\n\t\trequest: Request,\n\t\tresponse: Response,\n\t\tnext: NextFunction,\n\t) {\n\t\tconst projectKey = request.params.projectKey;\n\t\tconst storeKey = request.params.storeKey;\n\t\tconst grantType = request.query.grant_type || request.body.grant_type;\n\t\tif (!grantType) {\n\t\t\treturn next(\n\t\t\t\tnew CommercetoolsError<InvalidRequestError>(\n\t\t\t\t\t{\n\t\t\t\t\t\tcode: \"invalid_request\",\n\t\t\t\t\t\tmessage: \"Missing required parameter: grant_type.\",\n\t\t\t\t\t},\n\t\t\t\t\t400,\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\n\t\tif (grantType === \"password\") {\n\t\t\tconst username = request.query.username || request.body.username;\n\t\t\tconst password = hashPassword(\n\t\t\t\trequest.query.password || request.body.password,\n\t\t\t);\n\t\t\tconst scope =\n\t\t\t\trequest.query.scope?.toString() || request.body.scope?.toString();\n\n\t\t\tconst result = this.customerRepository.query(\n\t\t\t\t{ projectKey, storeKey },\n\t\t\t\t{\n\t\t\t\t\twhere: [`email = \"${username}\"`, `password = \"${password}\"`],\n\t\t\t\t},\n\t\t\t);\n\n\t\t\tif (result.count === 0) {\n\t\t\t\treturn next(\n\t\t\t\t\tnew CommercetoolsError<any>(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcode: \"invalid_customer_account_credentials\",\n\t\t\t\t\t\t\tmessage: \"Customer account with the given credentials not found.\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\t400,\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst customer = result.results[0];\n\t\t\tconst token = this.store.getCustomerToken(projectKey, customer.id, scope);\n\t\t\tresponse.status(200).send(token);\n\t\t\treturn;\n\t\t}\n\t}\n\n\tasync anonymousTokenHandler(\n\t\trequest: Request,\n\t\tresponse: Response,\n\t\tnext: NextFunction,\n\t) {\n\t\tconst projectKey = request.params.projectKey;\n\t\tconst grantType = request.query.grant_type || request.body.grant_type;\n\t\tif (!grantType) {\n\t\t\treturn next(\n\t\t\t\tnew CommercetoolsError<InvalidRequestError>(\n\t\t\t\t\t{\n\t\t\t\t\t\tcode: \"invalid_request\",\n\t\t\t\t\t\tmessage: \"Missing required parameter: grant_type.\",\n\t\t\t\t\t},\n\t\t\t\t\t400,\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\n\t\tif (grantType === \"client_credentials\") {\n\t\t\tconst scope =\n\t\t\t\trequest.query.scope?.toString() || request.body?.scope?.toString();\n\n\t\t\tconst anonymous_id = undefined;\n\n\t\t\tconst token = this.store.getAnonymousToken(\n\t\t\t\tprojectKey,\n\t\t\t\tanonymous_id,\n\t\t\t\tscope,\n\t\t\t);\n\t\t\tresponse.status(200).send(token);\n\t\t\treturn;\n\t\t}\n\t}\n}\n","import type { Config } from \"./config.ts\";\nimport { getBaseResourceProperties } from \"./helpers.ts\";\nimport type { GetParams } from \"./repositories/abstract.ts\";\nimport type { RepositoryMap } from \"./repositories/index.ts\";\nimport type { AbstractStorage } from \"./storage/index.ts\";\nimport type { ResourceMap, ResourceType } from \"./types.ts\";\n\nexport class ProjectAPI {\n\tprivate projectKey: string;\n\n\tprivate _storage: AbstractStorage;\n\n\tprivate _repositories: RepositoryMap;\n\n\treadonly config: Config;\n\n\tconstructor(projectKey: string, repositories: RepositoryMap, config: Config) {\n\t\tthis.projectKey = projectKey;\n\t\tthis.config = config;\n\t\tthis._storage = config.storage;\n\t\tthis._repositories = repositories;\n\t}\n\n\tadd<T extends keyof RepositoryMap & keyof ResourceMap>(\n\t\ttypeId: T,\n\t\tresource: ResourceMap[T],\n\t) {\n\t\tprocess.emitWarning(\n\t\t\t\"ctMock.add() is deprecated, create resources via regular create endpoints \" +\n\t\t\t\t\"or if you are really sure, use unsafeAdd() (but be aware of potential state issues)\",\n\t\t\t\"DeprecationWarning\",\n\t\t);\n\t\tthis.unsafeAdd(typeId, resource);\n\t}\n\n\tunsafeAdd<T extends keyof RepositoryMap & keyof ResourceMap>(\n\t\ttypeId: T,\n\t\tresource: ResourceMap[T],\n\t) {\n\t\tconst repository = this._repositories[typeId];\n\t\tif (repository) {\n\t\t\tthis._storage.add(this.projectKey, typeId, {\n\t\t\t\t...getBaseResourceProperties(),\n\t\t\t\t...resource,\n\t\t\t});\n\t\t} else {\n\t\t\tthrow new Error(`Service for ${typeId} not implemented yet`);\n\t\t}\n\t}\n\n\tget<RT extends ResourceType>(\n\t\ttypeId: RT,\n\t\tid: string,\n\t\tparams?: GetParams,\n\t): ResourceMap[RT] {\n\t\treturn this._storage.get(\n\t\t\tthis.projectKey,\n\t\t\ttypeId,\n\t\t\tid,\n\t\t\tparams,\n\t\t) as ResourceMap[RT];\n\t}\n\n\t// TODO: Not sure if we want to expose this...\n\tgetRepository<RT extends keyof RepositoryMap>(typeId: RT): RepositoryMap[RT] {\n\t\tconst repository = this._repositories[typeId];\n\t\tif (repository !== undefined) {\n\t\t\treturn repository as RepositoryMap[RT];\n\t\t}\n\t\tthrow new Error(\"No such repository\");\n\t}\n}\n","import type { ConcurrentModificationError } from \"@commercetools/platform-sdk\";\nimport { CommercetoolsError } from \"#src/exceptions.ts\";\n\nexport const checkConcurrentModification = (\n\tcurrentVersion: number,\n\texpectedVersion: number,\n\tidentifier: string,\n) => {\n\tif (currentVersion === expectedVersion) return;\n\tthrow new CommercetoolsError<ConcurrentModificationError>(\n\t\t{\n\t\t\tmessage: `Object ${identifier} has a different version than expected. Expected: ${expectedVersion} - Actual: ${currentVersion}.`,\n\t\t\tcurrentVersion: currentVersion,\n\t\t\tcode: \"ConcurrentModification\",\n\t\t},\n\t\t409,\n\t);\n};\n","import { isDeepStrictEqual } from \"node:util\";\nimport type {\n\tBaseResource,\n\tInvalidInputError,\n\tProject,\n\tQueryParam,\n\tResourceNotFoundError,\n\tUpdateAction,\n} from \"@commercetools/platform-sdk\";\nimport type { Config } from \"#src/config.ts\";\nimport { CommercetoolsError } from \"#src/exceptions.ts\";\nimport { cloneObject } from \"../helpers.ts\";\nimport type { AbstractStorage } from \"../storage/index.ts\";\nimport type {\n\tResourceMap,\n\tResourceType,\n\tShallowWritable,\n\tWritable,\n} from \"./../types.ts\";\nimport { checkConcurrentModification } from \"./errors.ts\";\n\nexport type QueryParams = {\n\texpand?: string[];\n\twhere?: string[];\n\toffset?: number;\n\tlimit?: number;\n\n\t// Predicate var values. Should always start with `var.`\n\t[key: string]: QueryParam;\n};\n\nexport type GetParams = {\n\texpand?: string[];\n};\n\nexport type RepositoryContext = {\n\tprojectKey: string;\n\tstoreKey?: string;\n};\n\nexport abstract class AbstractRepository<R extends BaseResource | Project> {\n\tprotected _storage: AbstractStorage;\n\n\tprotected config: Config;\n\n\tprotected actions: AbstractUpdateHandler | undefined;\n\n\tconstructor(config: Config) {\n\t\tthis.config = config;\n\t\tthis._storage = config.storage;\n\t}\n\n\tabstract saveNew({ projectKey }: RepositoryContext, resource: R): void;\n\n\tabstract saveUpdate(\n\t\t{ projectKey }: RepositoryContext,\n\t\tversion: number,\n\t\tresource: R,\n\t): void;\n\n\tabstract postProcessResource(context: RepositoryContext, resource: any): any;\n\n\tprocessUpdateActions(\n\t\tcontext: RepositoryContext,\n\t\tresource: R,\n\t\tversion: number,\n\t\tactions: UpdateAction[],\n\t): R {\n\t\tif (!this.actions) {\n\t\t\tthrow new Error(\"No actions defined\");\n\t\t}\n\n\t\tconst updatedResource = this.actions.apply(\n\t\t\tcontext,\n\t\t\tresource,\n\t\t\tversion,\n\t\t\tactions,\n\t\t);\n\n\t\t// If all actions succeeded we write the new version\n\t\t// to the storage.\n\t\tif (resource.version !== updatedResource.version) {\n\t\t\tthis.saveUpdate(context, version, updatedResource);\n\t\t}\n\n\t\tconst result = this.postProcessResource(context, updatedResource);\n\t\tif (!result) {\n\t\t\tthrow new Error(\"invalid post process action\");\n\t\t}\n\t\treturn result;\n\t}\n}\n\nexport abstract class AbstractResourceRepository<\n\tT extends ResourceType,\n> extends AbstractRepository<ResourceMap[T]> {\n\tprotected _typeId: T;\n\n\tconstructor(typeId: T, config: Config) {\n\t\tsuper(config);\n\t\tthis._typeId = typeId;\n\t}\n\n\tabstract create(context: RepositoryContext, draft: any): ResourceMap[T];\n\n\tprotected getTypeId(): T {\n\t\treturn this._typeId;\n\t}\n\n\tdelete(\n\t\tcontext: RepositoryContext,\n\t\tid: string,\n\t\tparams: GetParams = {},\n\t): ResourceMap[T] | null {\n\t\tconst resource = this._storage.delete(\n\t\t\tcontext.projectKey,\n\t\t\tthis.getTypeId(),\n\t\t\tid,\n\t\t\tparams,\n\t\t);\n\t\treturn resource\n\t\t\t? this.postProcessResource(context, resource, params)\n\t\t\t: null;\n\t}\n\n\tget(\n\t\tcontext: RepositoryContext,\n\t\tid: string,\n\t\tparams: GetParams = {},\n\t): ResourceMap[T] | null {\n\t\tconst resource = this._storage.get(\n\t\t\tcontext.projectKey,\n\t\t\tthis.getTypeId(),\n\t\t\tid,\n\t\t\tparams,\n\t\t);\n\t\treturn resource\n\t\t\t? this.postProcessResource(context, resource, params)\n\t\t\t: null;\n\t}\n\n\tgetByKey(\n\t\tcontext: RepositoryContext,\n\t\tkey: string,\n\t\tparams: GetParams = {},\n\t): ResourceMap[T] | null {\n\t\tconst resource = this._storage.getByKey(\n\t\t\tcontext.projectKey,\n\t\t\tthis.getTypeId(),\n\t\t\tkey,\n\t\t\tparams,\n\t\t);\n\t\treturn resource\n\t\t\t? this.postProcessResource(context, resource, params)\n\t\t\t: null;\n\t}\n\n\tpostProcessResource(\n\t\tcontext: RepositoryContext,\n\t\tresource: ResourceMap[T],\n\t\tparams?: GetParams,\n\t): ResourceMap[T] {\n\t\treturn resource;\n\t}\n\n\tquery(context: RepositoryContext, params: QueryParams = {}) {\n\t\tconst result = this._storage.query(context.projectKey, this.getTypeId(), {\n\t\t\t...params,\n\t\t});\n\n\t\tconst data = result.results.map((r) =>\n\t\t\tthis.postProcessResource(context, r as ResourceMap[T], {\n\t\t\t\texpand: params.expand,\n\t\t\t}),\n\t\t);\n\t\treturn {\n\t\t\t...result,\n\t\t\tresults: data,\n\t\t};\n\t}\n\n\tsaveNew(\n\t\tcontext: RepositoryContext,\n\t\tresource: ShallowWritable<ResourceMap[T]>,\n\t): ResourceMap[T] {\n\t\tresource.version = 1;\n\t\treturn this._storage.add(\n\t\t\tcontext.projectKey,\n\t\t\tthis.getTypeId(),\n\t\t\tresource as any,\n\t\t);\n\t}\n\n\tsaveUpdate(\n\t\tcontext: RepositoryContext,\n\t\tversion: number,\n\t\tresource: ShallowWritable<ResourceMap[T]>,\n\t) {\n\t\t// Check if the resource still exists.\n\t\tconst current = this._storage.get(\n\t\t\tcontext.projectKey,\n\t\t\tthis.getTypeId(),\n\t\t\tresource.id,\n\t\t);\n\t\tif (!current) {\n\t\t\tthrow new CommercetoolsError<ResourceNotFoundError>(\n\t\t\t\t{\n\t\t\t\t\tcode: \"ResourceNotFound\",\n\t\t\t\t\tmessage: \"Resource not found while updating\",\n\t\t\t\t},\n\t\t\t\t400,\n\t\t\t);\n\t\t}\n\n\t\tcheckConcurrentModification(current.version, version, resource.id);\n\n\t\tif (current.version === resource.version) {\n\t\t\tthrow new Error(\"Internal error: no changes to save\");\n\t\t}\n\t\tresource.lastModifiedAt = new Date().toISOString();\n\n\t\tthis._storage.add(context.projectKey, this.getTypeId(), resource as any);\n\n\t\treturn resource;\n\t}\n}\n\ntype UpdateActionHandlerMethod<A, T> = (\n\tcontext: RepositoryContext,\n\tresource: Writable<A>,\n\taction: T,\n) => void;\n\nexport type UpdateHandlerInterface<\n\tA extends BaseResource | Project,\n\tT extends UpdateAction,\n> = {\n\t[P in T as P[\"action\"]]: UpdateActionHandlerMethod<A, P>;\n};\n\nexport class AbstractUpdateHandler {\n\tconstructor(protected _storage: AbstractStorage) {\n\t\tif (!_storage) {\n\t\t\tthrow new Error(\"No storage provided\");\n\t\t}\n\t\tthis._storage = _storage;\n\t}\n\n\tapply<R extends BaseResource | Project>(\n\t\tcontext: RepositoryContext,\n\t\tresource: R,\n\t\tversion: number,\n\t\tactions: UpdateAction[],\n\t): R {\n\t\tconst updatedResource = cloneObject(resource) as ShallowWritable<R>;\n\t\tconst identifier = (resource as BaseResource).id\n\t\t\t? (resource as BaseResource).id\n\t\t\t: (resource as Project).key;\n\n\t\tfor (const action of actions) {\n\t\t\t// Validate if this action exists\n\t\t\t// @ts-expect-error\n\t\t\tif (this[action.action] === undefined) {\n\t\t\t\tthrow new CommercetoolsError<InvalidInputError>({\n\t\t\t\t\tcode: \"InvalidInput\",\n\t\t\t\t\tmessage: `Invalid action ${action.action}`,\n\t\t\t\t\terrors: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcode: \"InvalidInput\",\n\t\t\t\t\t\t\tmessage: `Invalid action ${action.action}`,\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t// @ts-expect-error\n\t\t\tconst updateFunc = this[action.action].bind(this);\n\n\t\t\tif (!updateFunc) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`No mock implemented for update action ${action.action}`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst beforeUpdate = cloneObject(resource);\n\t\t\tupdateFunc(context, updatedResource, action);\n\n\t\t\t// Check if the object is updated. We need to increase the version of\n\t\t\t// an object per action which does an actual modification.\n\t\t\t// This isn't the most performant method to do this (the update action\n\t\t\t// should return a flag) but for now the easiest.\n\t\t\tif (!isDeepStrictEqual(beforeUpdate, updatedResource)) {\n\t\t\t\t// We only check the version when there is an actual modification to\n\t\t\t\t// be stored.\n\t\t\t\tcheckConcurrentModification(resource.version, version, identifier);\n\n\t\t\t\tupdatedResource.version += 1;\n\t\t\t}\n\t\t}\n\t\treturn updatedResource;\n\t}\n}\n","import type {\n\tProductTailoring,\n\tProductTailoringUpdateAction,\n} from \"@commercetools/platform-sdk\";\nimport type { Config } from \"#src/config.ts\";\nimport type { RepositoryContext, UpdateHandlerInterface } from \"./abstract.ts\";\nimport {\n\tAbstractResourceRepository,\n\tAbstractUpdateHandler,\n} from \"./abstract.ts\";\n\nexport class ProductTailoringRepository extends AbstractResourceRepository<\"product-tailoring\"> {\n\tconstructor(config: Config) {\n\t\tsuper(\"product-tailoring\", config);\n\t\tthis.actions = new ProductTailoringUpdateHandler(this._storage);\n\t}\n\n\tcreate(context: RepositoryContext, draft: any): ProductTailoring {\n\t\tthrow new Error(\"Create method for product-tailoring not implemented.\");\n\t}\n}\n\nclass ProductTailoringUpdateHandler\n\textends AbstractUpdateHandler\n\timplements\n\t\tPartial<\n\t\t\tUpdateHandlerInterface<ProductTailoring, ProductTailoringUpdateAction>\n\t\t>\n{\n\tsetSlug() {\n\t\tthrow new Error(\"SetSlug method for product-tailoring not implemented.\");\n\t}\n}\n","import type {\n\t_Money,\n\tAddress,\n\tAssociate,\n\tAssociateDraft,\n\tAssociateRoleAssignment,\n\tAssociateRoleAssignmentDraft,\n\tAssociateRoleKeyReference,\n\tAssociateRoleReference,\n\tAssociateRoleResourceIdentifier,\n\tBaseAddress,\n\tBusinessUnitKeyReference,\n\tBusinessUnitReference,\n\tBusinessUnitResourceIdentifier,\n\tCentPrecisionMoney,\n\tCustomFields,\n\tCustomFieldsDraft,\n\tHighPrecisionMoney,\n\tHighPrecisionMoneyDraft,\n\tInvalidJsonInputError,\n\tPrice,\n\tPriceDraft,\n\tReference,\n\tReferencedResourceNotFoundError,\n\tResourceIdentifier,\n\tRoundingMode,\n\tStore,\n\tStoreKeyReference,\n\tStoreReference,\n\tStoreResourceIdentifier,\n\tType,\n} from \"@commercetools/platform-sdk\";\nimport { Decimal } from \"decimal.js/decimal\";\nimport type { Request } from \"express\";\nimport { v4 as uuidv4 } from \"uuid\";\nimport { CommercetoolsError } from \"#src/exceptions.ts\";\nimport type { AbstractStorage } from \"../storage/index.ts\";\nimport type { RepositoryContext } from \"./abstract.ts\";\n\nexport const createAddress = (\n\tbase: BaseAddress | undefined,\n\tprojectKey: string,\n\tstorage: AbstractStorage,\n): Address | undefined => {\n\tif (!base) return undefined;\n\n\tif (!base?.country) {\n\t\tthrow new Error(\"Country is required\");\n\t}\n\n\t// Generate a random 8-character alphanumeric string\n\t// which is what addresses use instead of uuid\n\tconst generateRandomId = (): string =>\n\t\tMath.random().toString(36).substring(2, 10).padEnd(8, \"0\");\n\treturn {\n\t\t...base,\n\t\tid: base.id ?? generateRandomId(),\n\t};\n};\n\nexport const createCustomFields = (\n\tdraft: CustomFieldsDraft | undefined,\n\tprojectKey: string,\n\tstorage: AbstractStorage,\n): CustomFields | undefined => {\n\tif (!draft) return undefined;\n\tif (!draft.type) return undefined;\n\tif (!draft.type.typeId) return undefined;\n\tconst typeResource = storage.getByResourceIdentifier(\n\t\tprojectKey,\n\t\tdraft.type,\n\t) as Type;\n\n\tif (!typeResource) {\n\t\tthrow new Error(\n\t\t\t`No type '${draft.type.typeId}' with id=${draft.type.id} or key=${draft.type.key}`,\n\t\t);\n\t}\n\n\treturn {\n\t\ttype: {\n\t\t\ttypeId: draft.type.typeId,\n\t\t\tid: typeResource.id,\n\t\t},\n\t\tfields: draft.fields ?? {},\n\t};\n};\n\nexport const createPrice = (draft: PriceDraft): Price => ({\n\tid: uuidv4(),\n\tvalue: createTypedMoney(draft.value),\n});\n\n/**\n * Rounds a decimal to the nearest whole number using the specified\n * (Commercetools) rounding mode.\n *\n * @see https://docs.commercetools.com/api/projects/carts#roundingmode\n */\nexport const roundDecimal = (decimal: Decimal, roundingMode: RoundingMode) => {\n\tswitch (roundingMode) {\n\t\tcase \"HalfEven\":\n\t\t\treturn decimal.toDecimalPlaces(0, Decimal.ROUND_HALF_EVEN);\n\t\tcase \"HalfUp\":\n\t\t\treturn decimal.toDecimalPlaces(0, Decimal.ROUND_HALF_UP);\n\t\tcase \"HalfDown\":\n\t\t\treturn decimal.toDecimalPlaces(0, Decimal.ROUND_HALF_DOWN);\n\t\tdefault:\n\t\t\tthrow new Error(`Unknown rounding mode: ${roundingMode}`);\n\t}\n};\n\nexport const createCentPrecisionMoney = (value: _Money): CentPrecisionMoney => {\n\t// Taken from https://docs.adyen.com/development-resources/currency-codes\n\tlet fractionDigits = 2;\n\tswitch (value.currencyCode.toUpperCase()) {\n\t\tcase \"BHD\":\n\t\tcase \"IQD\":\n\t\tcase \"JOD\":\n\t\tcase \"KWD\":\n\t\tcase \"LYD\":\n\t\tcase \"OMR\":\n\t\tcase \"TND\":\n\t\t\tfractionDigits = 3;\n\t\t\tbreak;\n\t\tcase \"CVE\":\n\t\tcase \"DJF\":\n\t\tcase \"GNF\":\n\t\tcase \"IDR\":\n\t\tcase \"JPY\":\n\t\tcase \"KMF\":\n\t\tcase \"KRW\":\n\t\tcase \"PYG\":\n\t\tcase \"RWF\":\n\t\tcase \"UGX\":\n\t\tcase \"VND\":\n\t\tcase \"VUV\":\n\t\tcase \"XAF\":\n\t\tcase \"XOF\":\n\t\tcase \"XPF\":\n\t\t\tfractionDigits = 0;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tfractionDigits = 2;\n\t}\n\n\tif ((value as HighPrecisionMoney & HighPrecisionMoneyDraft).preciseAmount) {\n\t\tthrow new Error(\"HighPrecisionMoney not supported\");\n\t}\n\n\treturn {\n\t\ttype: \"centPrecision\",\n\t\t// centAmont is only optional on HighPrecisionMoney, so this should never\n\t\t// fallback to 0\n\t\tcentAmount: value.centAmount ?? 0,\n\t\tcurrencyCode: value.currencyCode,\n\t\tfractionDigits: fractionDigits,\n\t};\n};\n\nexport const createTypedMoney = (value: _Money): CentPrecisionMoney => {\n\tconst result = createCentPrecisionMoney(value);\n\treturn result;\n};\n\nexport const resolveStoreReference = (\n\tref: StoreResourceIdentifier | undefined,\n\tprojectKey: string,\n\tstorage: AbstractStorage,\n): StoreKeyReference | undefined => {\n\tif (!ref) return undefined;\n\tconst resource = storage.getByResourceIdentifier(projectKey, ref);\n\tif (!resource) {\n\t\tthrow new Error(\"No such store\");\n\t}\n\n\tconst store = resource as Store;\n\treturn {\n\t\ttypeId: \"store\",\n\t\tkey: store.key,\n\t};\n};\n\nexport const getReferenceFromResourceIdentifier = <T extends Reference>(\n\tresourceIdentifier: ResourceIdentifier,\n\tprojectKey: string,\n\tstorage: AbstractStorage,\n): T => {\n\tif (!resourceIdentifier.id && !resourceIdentifier.key) {\n\t\tthrow new CommercetoolsError<InvalidJsonInputError>(\n\t\t\t{\n\t\t\t\tcode: \"InvalidJsonInput\",\n\t\t\t\tmessage: `${resourceIdentifier.typeId}: ResourceIdentifier requires an 'id' xor a 'key'`,\n\t\t\t\tdetailedErrorMessage: `ResourceIdentifier requires an 'id' xor a 'key'`,\n\t\t\t},\n\t\t\t400,\n\t\t);\n\t}\n\n\tconst resource = storage.getByResourceIdentifier(\n\t\tprojectKey,\n\t\tresourceIdentifier,\n\t);\n\tif (!resource) {\n\t\tconst errIdentifier = resourceIdentifier.key\n\t\t\t? `key '${resourceIdentifier.key}'`\n\t\t\t: `identifier '${resourceIdentifier.id}'`;\n\n\t\tthrow new CommercetoolsError<ReferencedResourceNotFoundError>(\n\t\t\t{\n\t\t\t\tcode: \"ReferencedResourceNotFound\",\n\t\t\t\ttypeId: resourceIdentifier.typeId,\n\t\t\t\tmessage: `The referenced object of type '${resourceIdentifier.typeId}' with '${errIdentifier}' was not found. It either doesn't exist, or it can't be accessed from this endpoint (e.g., if the endpoint filters by store or customer account).`,\n\t\t\t},\n\t\t\t400,\n\t\t);\n\t}\n\n\treturn {\n\t\ttypeId: resourceIdentifier.typeId,\n\t\tid: resource?.id,\n\t} as unknown as T;\n};\n\nexport const getStoreKeyReference = (\n\tid: StoreResourceIdentifier,\n\tprojectKey: string,\n\tstorage: AbstractStorage,\n): StoreKeyReference => {\n\tif (id.key) {\n\t\treturn {\n\t\t\ttypeId: \"store\",\n\t\t\tkey: id.key,\n\t\t};\n\t}\n\tconst value = getReferenceFromResourceIdentifier<StoreReference>(\n\t\tid,\n\t\tprojectKey,\n\t\tstorage,\n\t);\n\n\tif (!value.obj?.key) {\n\t\tthrow new Error(\"No store found for reference\");\n\t}\n\treturn {\n\t\ttypeId: \"store\",\n\t\tkey: value.obj?.key,\n\t};\n};\n\nexport const getRepositoryContext = (request: Request): RepositoryContext => ({\n\tprojectKey: request.params.projectKey,\n\tstoreKey: request.params.storeKey,\n});\n\nexport const createAssociate = (\n\ta: AssociateDraft,\n\tprojectKey: string,\n\tstorage: AbstractStorage,\n): Associate | undefined => {\n\tif (!a) return undefined;\n\n\tif (!a.associateRoleAssignments) {\n\t\tthrow new Error(\"AssociateRoleAssignments is required\");\n\t}\n\n\treturn {\n\t\tcustomer: getReferenceFromResourceIdentifier(\n\t\t\ta.customer,\n\t\t\tprojectKey,\n\t\t\tstorage,\n\t\t),\n\t\tassociateRoleAssignments: a.associateRoleAssignments?.map(\n\t\t\t(a: AssociateRoleAssignmentDraft): AssociateRoleAssignment => ({\n\t\t\t\tassociateRole: getAssociateRoleKeyReference(\n\t\t\t\t\ta.associateRole,\n\t\t\t\t\tprojectKey,\n\t\t\t\t\tstorage,\n\t\t\t\t),\n\t\t\t\tinheritance: a.inheritance as string,\n\t\t\t}),\n\t\t),\n\t};\n};\n\nexport const getAssociateRoleKeyReference = (\n\tid: AssociateRoleResourceIdentifier,\n\tprojectKey: string,\n\tstorage: AbstractStorage,\n): AssociateRoleKeyReference => {\n\tif (id.key) {\n\t\treturn {\n\t\t\ttypeId: \"associate-role\",\n\t\t\tkey: id.key,\n\t\t};\n\t}\n\n\tconst value = getReferenceFromResourceIdentifier<AssociateRoleReference>(\n\t\tid,\n\t\tprojectKey,\n\t\tstorage,\n\t);\n\n\tif (!value.obj?.key) {\n\t\tthrow new Error(\"No associate-role found for reference\");\n\t}\n\n\treturn {\n\t\ttypeId: \"associate-role\",\n\t\tkey: value.obj?.key,\n\t};\n};\n\nexport const getBusinessUnitKeyReference = (\n\tid: BusinessUnitResourceIdentifier,\n\tprojectKey: string,\n\tstorage: AbstractStorage,\n): BusinessUnitKeyReference => {\n\tif (id.key) {\n\t\treturn {\n\t\t\ttypeId: \"business-unit\",\n\t\t\tkey: id.key,\n\t\t};\n\t}\n\n\tconst value = getReferenceFromResourceIdentifier<BusinessUnitReference>(\n\t\tid,\n\t\tprojectKey,\n\t\tstorage,\n\t);\n\n\tif (!value.obj?.key) {\n\t\tthrow new Error(\"No business-unit found for reference\");\n\t}\n\n\treturn {\n\t\ttypeId: \"business-unit\",\n\t\tkey: value.obj?.key,\n\t};\n};\n","import type {\n\tCart,\n\tTaxCategory,\n\tTaxedItemPrice,\n\tTaxedPrice,\n\tTaxPortion,\n\tTaxRate,\n} from \"@commercetools/platform-sdk\";\nimport { createCentPrecisionMoney } from \"#src/repositories/helpers.ts\";\n\ntype TaxableResource = Pick<\n\tCart,\n\t\"lineItems\" | \"customLineItems\" | \"shippingInfo\" | \"totalPrice\"\n>;\n\nexport const calculateTaxTotals = (\n\tresource: TaxableResource,\n): {\n\ttaxedPrice?: TaxedPrice;\n\ttaxedShippingPrice?: TaxedItemPrice;\n} => {\n\tconst taxedItemPrices: TaxedItemPrice[] = [];\n\n\tresource.lineItems.forEach((item) => {\n\t\tif (item.taxedPrice) {\n\t\t\ttaxedItemPrices.push(item.taxedPrice);\n\t\t}\n\t});\n\n\tresource.customLineItems.forEach((item) => {\n\t\tif (item.taxedPrice) {\n\t\t\ttaxedItemPrices.push(item.taxedPrice);\n\t\t}\n\t});\n\n\tlet taxedShippingPrice: TaxedItemPrice | undefined;\n\tif (resource.shippingInfo?.taxedPrice) {\n\t\ttaxedShippingPrice = resource.shippingInfo.taxedPrice;\n\t\ttaxedItemPrices.push(resource.shippingInfo.taxedPrice);\n\t}\n\n\tif (!taxedItemPrices.length) {\n\t\treturn {\n\t\t\ttaxedPrice: undefined,\n\t\t\ttaxedShippingPrice,\n\t\t};\n\t}\n\n\tconst currencyCode = resource.totalPrice.currencyCode;\n\tconst toMoney = (centAmount: number) =>\n\t\tcreateCentPrecisionMoney({\n\t\t\tcurrencyCode,\n\t\t\tcentAmount,\n\t\t});\n\n\tlet totalNet = 0;\n\tlet totalGross = 0;\n\tlet totalTax = 0;\n\n\tconst taxPortionsByRate = new Map<\n\t\tstring,\n\t\t{ rate: number; name?: string; centAmount: number }\n\t>();\n\n\ttaxedItemPrices.forEach((price) => {\n\t\ttotalNet += price.totalNet.centAmount;\n\t\ttotalGross += price.totalGross.centAmount;\n\t\tconst priceTax = price.totalTax\n\t\t\t? price.totalTax.centAmount\n\t\t\t: price.totalGross.centAmount - price.totalNet.centAmount;\n\t\ttotalTax += Math.max(priceTax, 0);\n\n\t\tprice.taxPortions?.forEach((portion) => {\n\t\t\tconst key = `${portion.rate}-${portion.name ?? \"\"}`;\n\t\t\tconst existing = taxPortionsByRate.get(key) ?? {\n\t\t\t\trate: portion.rate,\n\t\t\t\tname: portion.name,\n\t\t\t\tcentAmount: 0,\n\t\t\t};\n\t\t\texisting.centAmount += portion.amount.centAmount;\n\t\t\ttaxPortionsByRate.set(key, existing);\n\t\t});\n\t});\n\n\tconst taxPortions: TaxPortion[] = Array.from(taxPortionsByRate.values()).map(\n\t\t(portion) => ({\n\t\t\trate: portion.rate,\n\t\t\tname: portion.name,\n\t\t\tamount: toMoney(portion.centAmount),\n\t\t}),\n\t);\n\n\treturn {\n\t\ttaxedPrice: {\n\t\t\ttotalNet: toMoney(totalNet),\n\t\t\ttotalGross: toMoney(totalGross),\n\t\t\ttaxPortions,\n\t\t\ttotalTax: totalTax > 0 ? toMoney(totalTax) : undefined,\n\t\t},\n\t\ttaxedShippingPrice,\n\t};\n};\n\nexport const buildTaxedPriceFromRate = (\n\tamount: number,\n\tcurrencyCode: string,\n\ttaxRate?: TaxRate,\n): TaxedItemPrice | undefined => {\n\tif (!taxRate) {\n\t\treturn undefined;\n\t}\n\n\tconst toMoney = (centAmount: number) =>\n\t\tcreateCentPrecisionMoney({\n\t\t\ttype: \"centPrecision\",\n\t\t\tcurrencyCode,\n\t\t\tcentAmount,\n\t\t});\n\n\tlet netAmount: number;\n\tlet grossAmount: number;\n\tlet taxAmount: number;\n\n\tif (taxRate.includedInPrice) {\n\t\tgrossAmount = amount;\n\t\ttaxAmount = Math.round(\n\t\t\t(grossAmount * taxRate.amount) / (1 + taxRate.amount),\n\t\t);\n\t\tnetAmount = grossAmount - taxAmount;\n\t} else {\n\t\tnetAmount = amount;\n\t\ttaxAmount = Math.round(netAmount * taxRate.amount);\n\t\tgrossAmount = netAmount + taxAmount;\n\t}\n\n\treturn {\n\t\ttotalNet: toMoney(netAmount),\n\t\ttotalGross: toMoney(grossAmount),\n\t\ttotalTax: taxAmount > 0 ? toMoney(taxAmount) : undefined,\n\t\ttaxPortions:\n\t\t\ttaxAmount > 0\n\t\t\t\t? [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\trate: taxRate.amount,\n\t\t\t\t\t\t\tname: taxRate.name,\n\t\t\t\t\t\t\tamount: toMoney(taxAmount),\n\t\t\t\t\t\t},\n\t\t\t\t\t]\n\t\t\t\t: [],\n\t};\n};\n\nexport const calculateTaxedPriceFromRate = (\n\tamount: number,\n\tcurrencyCode: string,\n\ttaxRate?: TaxRate,\n): TaxedItemPrice | undefined =>\n\tbuildTaxedPriceFromRate(amount, currencyCode, taxRate);\n\nexport const calculateTaxedPrice = (\n\tamount: number,\n\ttaxCategory: TaxCategory | undefined,\n\tcurrency: string,\n\tcountry: string | undefined,\n): TaxedPrice | undefined => {\n\tif (!taxCategory || !taxCategory.rates.length) {\n\t\treturn undefined;\n\t}\n\n\tconst taxRate =\n\t\ttaxCategory.rates.find(\n\t\t\t(rate) => !rate.country || rate.country === country,\n\t\t) || taxCategory.rates[0];\n\n\tconst taxedItemPrice = buildTaxedPriceFromRate(amount, currency, taxRate);\n\tif (!taxedItemPrice) {\n\t\treturn undefined;\n\t}\n\n\treturn {\n\t\ttotalNet: taxedItemPrice.totalNet,\n\t\ttotalGross: taxedItemPrice.totalGross,\n\t\ttaxPortions: taxedItemPrice.taxPortions,\n\t\ttotalTax: taxedItemPrice.totalTax,\n\t};\n};\n","import type {\n\tCart,\n\tCartValueTier,\n\tCentPrecisionMoney,\n\tInvalidOperationError,\n\tMissingTaxRateForCountryError,\n\tShippingInfo,\n\tShippingMethod,\n\tShippingRate,\n\tShippingRatePriceTier,\n\tTaxedItemPrice,\n\tTaxPortion,\n} from \"@commercetools/platform-sdk\";\nimport { Decimal } from \"decimal.js\";\nimport { CommercetoolsError } from \"./exceptions.ts\";\nimport type { GetParams, RepositoryContext } from \"./repositories/abstract.ts\";\nimport {\n\tcreateCentPrecisionMoney,\n\troundDecimal,\n} from \"./repositories/helpers.ts\";\nimport type { AbstractStorage } from \"./storage/abstract.ts\";\n\nexport const markMatchingShippingRate = (\n\tcart: Cart,\n\tshippingRate: ShippingRate,\n): ShippingRate => {\n\tconst isMatching =\n\t\tshippingRate.price.currencyCode === cart.totalPrice.currencyCode;\n\treturn {\n\t\t...shippingRate,\n\t\ttiers: markMatchingShippingRatePriceTiers(cart, shippingRate.tiers),\n\t\tisMatching: isMatching,\n\t};\n};\n\nexport const markMatchingShippingRatePriceTiers = (\n\tcart: Cart,\n\ttiers: ShippingRatePriceTier[],\n): ShippingRatePriceTier[] => {\n\tif (tiers.length === 0) {\n\t\treturn [];\n\t}\n\n\tif (new Set(tiers.map((tier) => tier.type)).size > 1) {\n\t\tthrow new Error(\"Can't handle multiple types of tiers\");\n\t}\n\n\tconst tierType = tiers[0].type;\n\tswitch (tierType) {\n\t\tcase \"CartValue\":\n\t\t\treturn markMatchingCartValueTiers(cart, tiers as CartValueTier[]);\n\t\t// case 'CartClassification':\n\t\t// \treturn markMatchingCartClassificationTiers(cart, tiers)\n\t\t// case 'CartScore':\n\t\t// \treturn markMatchingCartScoreTiers(cart, tiers)\n\t\tdefault:\n\t\t\tthrow new Error(`Unsupported tier type: ${tierType}`);\n\t}\n};\n\nconst markMatchingCartValueTiers = (\n\tcart: Cart,\n\ttiers: readonly CartValueTier[],\n): ShippingRatePriceTier[] => {\n\t// Sort tiers from high to low since we only want to match the highest tier\n\tconst sortedTiers = [...tiers].sort(\n\t\t(a, b) => b.minimumCentAmount - a.minimumCentAmount,\n\t);\n\n\t// Find the first tier that matches the cart and set the flag. We push\n\t// the results into a map so that we can output the tiers in the same order as\n\t// we received them.\n\tconst result: Record<number, ShippingRatePriceTier> = {};\n\tlet hasMatchingTier = false;\n\tfor (const tier of sortedTiers) {\n\t\tconst isMatching =\n\t\t\t!hasMatchingTier &&\n\t\t\tcart.totalPrice.currencyCode === tier.price.currencyCode &&\n\t\t\tcart.totalPrice.centAmount >= tier.minimumCentAmount;\n\n\t\tif (isMatching) hasMatchingTier = true;\n\t\tresult[tier.minimumCentAmount] = {\n\t\t\t...tier,\n\t\t\tisMatching: isMatching,\n\t\t};\n\t}\n\n\treturn tiers.map((tier) => result[tier.minimumCentAmount]);\n};\n\n/*\n * Retrieves all the ShippingMethods that can ship to the shipping address of\n * the given Cart. Each ShippingMethod contains exactly one ShippingRate with\n * the flag isMatching set to true. This ShippingRate is used when the\n * ShippingMethod is added to the Cart.\n */\nexport const getShippingMethodsMatchingCart = (\n\tcontext: RepositoryContext,\n\tstorage: AbstractStorage,\n\tcart: Cart,\n\tparams: GetParams = {},\n) => {\n\tif (!cart.shippingAddress?.country) {\n\t\tthrow new CommercetoolsError<InvalidOperationError>({\n\t\t\tcode: \"InvalidOperation\",\n\t\t\tmessage: `The cart with ID '${cart.id}' does not have a shipping address set.`,\n\t\t});\n\t}\n\n\t// Get all shipping methods that have a zone that matches the shipping address\n\tconst zones = storage.query<\"zone\">(context.projectKey, \"zone\", {\n\t\twhere: [`locations(country=\"${cart.shippingAddress.country}\"))`],\n\t\tlimit: 100,\n\t});\n\tconst zoneIds = zones.results.map((zone) => zone.id);\n\tconst shippingMethods = storage.query<\"shipping-method\">(\n\t\tcontext.projectKey,\n\t\t\"shipping-method\",\n\t\t{\n\t\t\twhere: [\n\t\t\t\t\"zoneRates(zone(id in (:zoneIds)))\",\n\t\t\t\t`zoneRates(shippingRates(price(currencyCode=\"${cart.totalPrice.currencyCode}\")))`,\n\t\t\t],\n\t\t\t\"var.zoneIds\": zoneIds,\n\t\t\texpand: params.expand,\n\t\t},\n\t);\n\n\t// Make sure that each shipping method has exactly one shipping rate and\n\t// that the shipping rate is marked as matching\n\tconst results = shippingMethods.results\n\t\t.map((shippingMethod) => {\n\t\t\t// Iterate through the zoneRates, process the shipping rates and filter\n\t\t\t// out all zoneRates which have no matching shipping rates left\n\t\t\tconst rates = shippingMethod.zoneRates\n\t\t\t\t.map((zoneRate) => ({\n\t\t\t\t\tzone: zoneRate.zone,\n\n\t\t\t\t\t// Iterate through the shippingRates and mark the matching ones\n\t\t\t\t\t// then we filter out the non-matching ones\n\t\t\t\t\tshippingRates: zoneRate.shippingRates\n\t\t\t\t\t\t.map((rate) => markMatchingShippingRate(cart, rate))\n\t\t\t\t\t\t.filter((rate) => rate.isMatching),\n\t\t\t\t}))\n\t\t\t\t.filter((zoneRate) => zoneRate.shippingRates.length > 0);\n\n\t\t\treturn {\n\t\t\t\t...shippingMethod,\n\t\t\t\tzoneRates: rates,\n\t\t\t};\n\t\t})\n\t\t.filter((shippingMethod) => shippingMethod.zoneRates.length > 0);\n\n\treturn {\n\t\t...shippingMethods,\n\t\tresults: results,\n\t};\n};\n\n/**\n * Interface for cart-like objects that can be used for shipping calculations\n */\ninterface ShippingCalculationSource {\n\tid: string;\n\ttotalPrice: CentPrecisionMoney;\n\tshippingAddress?: {\n\t\tcountry: string;\n\t\t[key: string]: any;\n\t};\n\ttaxRoundingMode?: string;\n}\n\n/**\n * Creates shipping info from a shipping method, handling all tax calculations and pricing logic.\n */\nexport const createShippingInfoFromMethod = (\n\tcontext: RepositoryContext,\n\tstorage: AbstractStorage,\n\tresource: ShippingCalculationSource,\n\tmethod: ShippingMethod,\n): Omit<ShippingInfo, \"deliveries\"> => {\n\tconst country = resource.shippingAddress!.country;\n\n\t// There should only be one zone rate matching the address, since\n\t// Locations cannot be assigned to more than one zone.\n\t// See https://docs.commercetools.com/api/projects/zones#location\n\tconst zoneRate = method.zoneRates.find((rate) =>\n\t\trate.zone.obj?.locations.some((loc) => loc.country === country),\n\t);\n\n\tif (!zoneRate) {\n\t\t// This shouldn't happen because getShippingMethodsMatchingCart already\n\t\t// filtered out shipping methods without any zones matching the address\n\t\tthrow new Error(\"Zone rate not found\");\n\t}\n\n\t// Shipping rates are defined by currency, and getShippingMethodsMatchingCart\n\t// also matches on currency, so there should only be one in the array.\n\t// See https://docs.commercetools.com/api/projects/shippingMethods#zonerate\n\tconst shippingRate = zoneRate.shippingRates[0];\n\tif (!shippingRate) {\n\t\t// This shouldn't happen because getShippingMethodsMatchingCart already\n\t\t// filtered out shipping methods without any matching rates\n\t\tthrow new Error(\"Shipping rate not found\");\n\t}\n\n\tconst taxCategory = storage.getByResourceIdentifier<\"tax-category\">(\n\t\tcontext.projectKey,\n\t\tmethod.taxCategory,\n\t);\n\n\t// TODO: match state in addition to country\n\tconst taxRate = taxCategory.rates.find((rate) => rate.country === country);\n\n\tif (!taxRate) {\n\t\tthrow new CommercetoolsError<MissingTaxRateForCountryError>({\n\t\t\tcode: \"MissingTaxRateForCountry\",\n\t\t\tmessage: `Tax category '${taxCategory.id}' is missing a tax rate for country '${country}'.`,\n\t\t\ttaxCategoryId: taxCategory.id,\n\t\t});\n\t}\n\n\tconst shippingRateTier = shippingRate.tiers.find((tier) => tier.isMatching);\n\tif (shippingRateTier && shippingRateTier.type !== \"CartValue\") {\n\t\tthrow new Error(\"Non-CartValue shipping rate tier is not supported\");\n\t}\n\n\tlet shippingPrice = shippingRateTier\n\t\t? createCentPrecisionMoney(shippingRateTier.price)\n\t\t: shippingRate.price;\n\n\t// Handle freeAbove: if total is above the freeAbove threshold, shipping is free\n\tif (\n\t\tshippingRate.freeAbove &&\n\t\tshippingRate.freeAbove.currencyCode === resource.totalPrice.currencyCode &&\n\t\tresource.totalPrice.centAmount >= shippingRate.freeAbove.centAmount\n\t) {\n\t\tshippingPrice = {\n\t\t\t...shippingPrice,\n\t\t\tcentAmount: 0,\n\t\t};\n\t}\n\n\t// Calculate tax amounts\n\tconst totalGross: CentPrecisionMoney = taxRate.includedInPrice\n\t\t? shippingPrice\n\t\t: {\n\t\t\t\t...shippingPrice,\n\t\t\t\tcentAmount: roundDecimal(\n\t\t\t\t\tnew Decimal(shippingPrice.centAmount).mul(1 + taxRate.amount),\n\t\t\t\t\tresource.taxRoundingMode || \"HalfEven\",\n\t\t\t\t).toNumber(),\n\t\t\t};\n\n\tconst totalNet: CentPrecisionMoney = taxRate.includedInPrice\n\t\t? {\n\t\t\t\t...shippingPrice,\n\t\t\t\tcentAmount: roundDecimal(\n\t\t\t\t\tnew Decimal(shippingPrice.centAmount).div(1 + taxRate.amount),\n\t\t\t\t\tresource.taxRoundingMode || \"HalfEven\",\n\t\t\t\t).toNumber(),\n\t\t\t}\n\t\t: shippingPrice;\n\n\tconst taxPortions: TaxPortion[] = [\n\t\t{\n\t\t\tname: taxRate.name,\n\t\t\trate: taxRate.amount,\n\t\t\tamount: {\n\t\t\t\t...shippingPrice,\n\t\t\t\tcentAmount: totalGross.centAmount - totalNet.centAmount,\n\t\t\t},\n\t\t},\n\t];\n\n\tconst totalTax: CentPrecisionMoney = {\n\t\t...shippingPrice,\n\t\tcentAmount: taxPortions.reduce(\n\t\t\t(acc, portion) => acc + portion.amount.centAmount,\n\t\t\t0,\n\t\t),\n\t};\n\n\tconst taxedPrice: TaxedItemPrice = {\n\t\ttotalNet,\n\t\ttotalGross,\n\t\ttaxPortions,\n\t\ttotalTax,\n\t};\n\n\treturn {\n\t\tshippingMethod: {\n\t\t\ttypeId: \"shipping-method\" as const,\n\t\t\tid: method.id,\n\t\t},\n\t\tshippingMethodName: method.name,\n\t\tprice: shippingPrice,\n\t\tshippingRate,\n\t\ttaxedPrice,\n\t\ttaxRate,\n\t\ttaxCategory: method.taxCategory,\n\t\tshippingMethodState: \"MatchesCart\",\n\t};\n};\n","import type {\n\tCart,\n\tCustomLineItem,\n\tCustomLineItemDraft,\n\tLineItem,\n\tPrice,\n\tTaxCategory,\n\tTaxCategoryReference,\n} from \"@commercetools/platform-sdk\";\nimport { v4 as uuidv4 } from \"uuid\";\nimport { calculateTaxedPrice } from \"#src/lib/tax.ts\";\nimport type { AbstractStorage } from \"#src/storage/abstract.ts\";\nimport {\n\tcreateCentPrecisionMoney,\n\tcreateCustomFields,\n\tcreateTypedMoney,\n\tgetReferenceFromResourceIdentifier,\n} from \"../helpers.ts\";\n\nexport const selectPrice = ({\n\tprices,\n\tcurrency,\n\tcountry,\n}: {\n\tprices: Price[] | undefined;\n\tcurrency: string;\n\tcountry: string | undefined;\n}): Price | undefined => {\n\tif (!prices) {\n\t\treturn undefined;\n\t}\n\n\t// Quick-and-dirty way of selecting price based on the given currency and country.\n\t// Can be improved later to give more priority to exact matches over\n\t// 'all country' matches, and include customer groups in the mix as well\n\treturn prices.find((price) => {\n\t\tconst countryMatch = !price.country || price.country === country;\n\t\tconst currencyMatch = price.value.currencyCode === currency;\n\t\treturn countryMatch && currencyMatch;\n\t});\n};\n\nexport const calculateLineItemTotalPrice = (lineItem: LineItem): number =>\n\tlineItem.price?.value.centAmount * lineItem.quantity;\n\nexport const calculateCartTotalPrice = (cart: Cart): number => {\n\tconst lineItemsTotal = cart.lineItems.reduce(\n\t\t(cur, item) => cur + item.totalPrice.centAmount,\n\t\t0,\n\t);\n\tconst customLineItemsTotal = cart.customLineItems.reduce(\n\t\t(cur, item) => cur + item.totalPrice.centAmount,\n\t\t0,\n\t);\n\treturn lineItemsTotal + customLineItemsTotal;\n};\n\nexport const createCustomLineItemFromDraft = (\n\tprojectKey: string,\n\tdraft: CustomLineItemDraft,\n\tstorage: AbstractStorage,\n\tcountry?: string,\n): CustomLineItem => {\n\tconst quantity = draft.quantity ?? 1;\n\n\tconst taxCategoryRef = draft.taxCategory\n\t\t? getReferenceFromResourceIdentifier<TaxCategoryReference>(\n\t\t\t\tdraft.taxCategory,\n\t\t\t\tprojectKey,\n\t\t\t\tstorage,\n\t\t\t)\n\t\t: undefined;\n\n\tlet taxCategory: TaxCategory | undefined;\n\tif (taxCategoryRef) {\n\t\ttry {\n\t\t\ttaxCategory =\n\t\t\t\tstorage.get(projectKey, \"tax-category\", taxCategoryRef.id, {}) ||\n\t\t\t\tundefined;\n\t\t} catch (_error) {\n\t\t\t// Tax category not found, continue without tax calculation\n\t\t}\n\t}\n\n\tconst totalPrice = createCentPrecisionMoney({\n\t\t...draft.money,\n\t\tcentAmount: (draft.money.centAmount ?? 0) * quantity,\n\t});\n\n\tconst taxedPrice = taxCategory\n\t\t? calculateTaxedPrice(\n\t\t\t\ttotalPrice.centAmount,\n\t\t\t\ttaxCategory,\n\t\t\t\ttotalPrice.currencyCode,\n\t\t\t\tcountry,\n\t\t\t)\n\t\t: undefined;\n\n\tconst taxRate = taxCategory\n\t\t? taxCategory.rates.find(\n\t\t\t\t(rate) => !rate.country || rate.country === country,\n\t\t\t)\n\t\t: undefined;\n\n\treturn {\n\t\tid: uuidv4(),\n\t\tkey: draft.key,\n\t\tname: draft.name,\n\t\tmoney: createTypedMoney(draft.money),\n\t\tslug: draft.slug,\n\t\tquantity: draft.quantity ?? 1,\n\t\tstate: [],\n\t\ttaxCategory: taxCategoryRef,\n\t\ttaxRate,\n\t\ttaxedPrice,\n\t\tcustom: createCustomFields(draft.custom, projectKey, storage),\n\t\tdiscountedPricePerQuantity: [],\n\t\tperMethodTaxRate: [],\n\t\tpriceMode: draft.priceMode ?? \"Standard\",\n\t\ttotalPrice,\n\t\ttaxedPricePortions: [],\n\t};\n};\n","import type {\n\tAddress,\n\tAddressDraft,\n\tCart,\n\tCartAddCustomLineItemAction,\n\tCartAddItemShippingAddressAction,\n\tCartAddLineItemAction,\n\tCartChangeCustomLineItemMoneyAction,\n\tCartChangeCustomLineItemQuantityAction,\n\tCartChangeLineItemQuantityAction,\n\tCartChangeTaxRoundingModeAction,\n\tCartRemoveCustomLineItemAction,\n\tCartRemoveDiscountCodeAction,\n\tCartRemoveLineItemAction,\n\tCartRemoveShippingMethodAction,\n\tCartSetAnonymousIdAction,\n\tCartSetBillingAddressAction,\n\tCartSetBillingAddressCustomTypeAction,\n\tCartSetCountryAction,\n\tCartSetCustomerEmailAction,\n\tCartSetCustomerIdAction,\n\tCartSetCustomFieldAction,\n\tCartSetCustomShippingMethodAction,\n\tCartSetCustomTypeAction,\n\tCartSetDirectDiscountsAction,\n\tCartSetLineItemCustomFieldAction,\n\tCartSetLineItemCustomTypeAction,\n\tCartSetLineItemPriceAction,\n\tCartSetLineItemShippingDetailsAction,\n\tCartSetLocaleAction,\n\tCartSetShippingAddressAction,\n\tCartSetShippingAddressCustomFieldAction,\n\tCartSetShippingAddressCustomTypeAction,\n\tCartSetShippingMethodAction,\n\tCartUpdateAction,\n\tCustomFields,\n\tGeneralError,\n\tItemShippingDetails,\n\tLineItem,\n\tProduct,\n\tProductPagedQueryResponse,\n\tProductVariant,\n} from \"@commercetools/platform-sdk\";\nimport type {\n\tCustomLineItem,\n\tDirectDiscount,\n} from \"@commercetools/platform-sdk/dist/declarations/src/generated/models/cart\";\nimport type { ShippingMethodResourceIdentifier } from \"@commercetools/platform-sdk/dist/declarations/src/generated/models/shipping-method\";\nimport { v4 as uuidv4 } from \"uuid\";\nimport { CommercetoolsError } from \"#src/exceptions.ts\";\nimport type { Writable } from \"#src/types.ts\";\nimport type { UpdateHandlerInterface } from \"../abstract.ts\";\nimport { AbstractUpdateHandler, type RepositoryContext } from \"../abstract.ts\";\nimport {\n\tcreateAddress,\n\tcreateCentPrecisionMoney,\n\tcreateCustomFields,\n\tcreateTypedMoney,\n} from \"../helpers.ts\";\nimport {\n\tcalculateCartTotalPrice,\n\tcalculateLineItemTotalPrice,\n\tcreateCustomLineItemFromDraft,\n\tselectPrice,\n} from \"./helpers.ts\";\nimport type { CartRepository } from \"./index.ts\";\n\nexport class CartUpdateHandler\n\textends AbstractUpdateHandler\n\timplements Partial<UpdateHandlerInterface<Cart, CartUpdateAction>>\n{\n\tprivate repository: CartRepository;\n\n\tconstructor(storage: any, repository: CartRepository) {\n\t\tsuper(storage);\n\t\tthis.repository = repository;\n\t}\n\taddItemShippingAddress(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Cart>,\n\t\t{ action, address }: CartAddItemShippingAddressAction,\n\t) {\n\t\tconst newAddress = createAddress(\n\t\t\taddress,\n\t\t\tcontext.projectKey,\n\t\t\tthis._storage,\n\t\t);\n\t\tif (newAddress) {\n\t\t\tresource.itemShippingAddresses.push(newAddress);\n\t\t}\n\t}\n\n\taddLineItem(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Cart>,\n\t\t{\n\t\t\tproductId,\n\t\t\tvariantId,\n\t\t\tsku,\n\t\t\tcustom,\n\t\t\tquantity = 1,\n\t\t\taddedAt,\n\t\t\tkey,\n\t\t}: CartAddLineItemAction,\n\t) {\n\t\tlet product: Product | null = null;\n\n\t\tif (productId && variantId) {\n\t\t\t// Fetch product and variant by ID\n\t\t\tproduct = this._storage.get(context.projectKey, \"product\", productId, {});\n\t\t} else if (sku) {\n\t\t\t// Fetch product and variant by SKU\n\t\t\tconst items = this._storage.query(context.projectKey, \"product\", {\n\t\t\t\twhere: [\n\t\t\t\t\t`masterData(current(masterVariant(sku=\"${sku}\"))) or masterData(current(variants(sku=\"${sku}\")))`,\n\t\t\t\t],\n\t\t\t}) as ProductPagedQueryResponse;\n\n\t\t\tif (items.count === 1) {\n\t\t\t\tproduct = items.results[0];\n\t\t\t}\n\t\t}\n\n\t\tif (!product) {\n\t\t\t// Check if product is found\n\t\t\tthrow new CommercetoolsError<GeneralError>({\n\t\t\t\tcode: \"General\",\n\t\t\t\tmessage: sku\n\t\t\t\t\t? `A product containing a variant with SKU '${sku}' not found.`\n\t\t\t\t\t: `A product with ID '${productId}' not found.`,\n\t\t\t});\n\t\t}\n\n\t\t// Find matching variant\n\t\tconst variant: ProductVariant | undefined = [\n\t\t\tproduct.masterData.current.masterVariant,\n\t\t\t...product.masterData.current.variants,\n\t\t].find((x) => {\n\t\t\tif (sku) return x.sku === sku;\n\t\t\tif (variantId) return x.id === variantId;\n\t\t\treturn false;\n\t\t});\n\n\t\tif (!variant) {\n\t\t\t// Check if variant is found\n\t\t\tthrow new CommercetoolsError<GeneralError>({\n\t\t\t\tcode: \"General\",\n\t\t\t\tmessage: sku\n\t\t\t\t\t? `A variant with SKU '${sku}' for product '${product.id}' not found.`\n\t\t\t\t\t: `A variant with ID '${variantId}' for product '${product.id}' not found.`,\n\t\t\t});\n\t\t}\n\n\t\tconst alreadyAdded = resource.lineItems.some(\n\t\t\t(x) => x.productId === product?.id && x.variant.id === variant?.id,\n\t\t);\n\t\tif (alreadyAdded) {\n\t\t\t// increase quantity and update total price\n\t\t\tresource.lineItems.forEach((x) => {\n\t\t\t\tif (x.productId === product?.id && x.variant.id === variant?.id) {\n\t\t\t\t\tx.quantity += quantity;\n\t\t\t\t\tx.totalPrice.centAmount = calculateLineItemTotalPrice(x);\n\t\t\t\t}\n\t\t\t});\n\t\t} else {\n\t\t\t// add line item\n\t\t\tif (!variant.prices?.length) {\n\t\t\t\tthrow new CommercetoolsError<GeneralError>({\n\t\t\t\t\tcode: \"General\",\n\t\t\t\t\tmessage: `A product with ID '${productId}' doesn't have any prices.`,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tconst currency = resource.totalPrice.currencyCode;\n\n\t\t\tconst price = selectPrice({\n\t\t\t\tprices: variant.prices,\n\t\t\t\tcurrency,\n\t\t\t\tcountry: resource.country,\n\t\t\t});\n\t\t\tif (!price) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`No valid price found for ${productId} for country ${resource.country} and currency ${currency}`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tresource.lineItems.push({\n\t\t\t\tid: uuidv4(),\n\t\t\t\tkey,\n\t\t\t\taddedAt: addedAt ? addedAt : new Date().toISOString(),\n\t\t\t\tproductId: product.id,\n\t\t\t\tproductKey: product.key,\n\t\t\t\tproductSlug: product.masterData.current.slug,\n\t\t\t\tproductType: product.productType,\n\t\t\t\tname: product.masterData.current.name,\n\t\t\t\tvariant,\n\t\t\t\tprice: price,\n\t\t\t\ttaxedPricePortions: [],\n\t\t\t\tperMethodTaxRate: [],\n\t\t\t\ttotalPrice: {\n\t\t\t\t\t...price.value,\n\t\t\t\t\ttype: \"centPrecision\",\n\t\t\t\t\tcentAmount: price.value.centAmount * quantity,\n\t\t\t\t},\n\t\t\t\tquantity,\n\t\t\t\tdiscountedPricePerQuantity: [],\n\t\t\t\tlineItemMode: \"Standard\",\n\t\t\t\tpriceMode: \"Platform\",\n\t\t\t\tstate: [],\n\t\t\t\tcustom: createCustomFields(custom, context.projectKey, this._storage),\n\t\t\t});\n\t\t}\n\n\t\t// Update cart total price\n\t\tresource.totalPrice.centAmount = calculateCartTotalPrice(resource);\n\t}\n\n\tchangeLineItemQuantity(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Cart>,\n\t\t{ lineItemId, lineItemKey, quantity }: CartChangeLineItemQuantityAction,\n\t) {\n\t\tlet lineItem: Writable<LineItem> | undefined;\n\n\t\tif (lineItemId) {\n\t\t\tlineItem = resource.lineItems.find((x) => x.id === lineItemId);\n\t\t\tif (!lineItem) {\n\t\t\t\tthrow new CommercetoolsError<GeneralError>({\n\t\t\t\t\tcode: \"General\",\n\t\t\t\t\tmessage: `A line item with ID '${lineItemId}' not found.`,\n\t\t\t\t});\n\t\t\t}\n\t\t} else if (lineItemKey) {\n\t\t\tlineItem = resource.lineItems.find((x) => x.id === lineItemId);\n\t\t\tif (!lineItem) {\n\t\t\t\tthrow new CommercetoolsError<GeneralError>({\n\t\t\t\t\tcode: \"General\",\n\t\t\t\t\tmessage: `A line item with Key '${lineItemKey}' not found.`,\n\t\t\t\t});\n\t\t\t}\n\t\t} else {\n\t\t\tthrow new CommercetoolsError<GeneralError>({\n\t\t\t\tcode: \"General\",\n\t\t\t\tmessage: \"Either lineItemid or lineItemKey needs to be provided.\",\n\t\t\t});\n\t\t}\n\n\t\tif (quantity === 0) {\n\t\t\t// delete line item\n\t\t\tresource.lineItems = resource.lineItems.filter(\n\t\t\t\t(x) => x.id !== lineItemId,\n\t\t\t);\n\t\t} else {\n\t\t\tresource.lineItems.forEach((x) => {\n\t\t\t\tif (x.id === lineItemId && quantity) {\n\t\t\t\t\tx.quantity = quantity;\n\t\t\t\t\tx.totalPrice.centAmount = calculateLineItemTotalPrice(x);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\t// Update cart total price\n\t\tresource.totalPrice.centAmount = calculateCartTotalPrice(resource);\n\t}\n\n\tchangeTaxRoundingMode(\n\t\t_context: RepositoryContext,\n\t\tresource: Writable<Cart>,\n\t\t{ taxRoundingMode }: CartChangeTaxRoundingModeAction,\n\t) {\n\t\tresource.taxRoundingMode = taxRoundingMode;\n\t}\n\n\trecalculate() {\n\t\t// Dummy action when triggering a recalculation of the cart\n\t\t//\n\t\t// From commercetools documentation:\n\t\t// This update action does not set any Cart field in particular,\n\t\t// but it triggers several Cart updates to bring prices and discounts to the latest state.\n\t\t// Those can become stale over time when no Cart updates have been performed for a while\n\t\t// and prices on related Products have changed in the meanwhile.\n\t}\n\n\tremoveDiscountCode(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Cart>,\n\t\t{ discountCode }: CartRemoveDiscountCodeAction,\n\t) {\n\t\tresource.discountCodes = resource.discountCodes.filter(\n\t\t\t(code) => code.discountCode.id !== discountCode.id,\n\t\t);\n\t}\n\n\tremoveLineItem(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Cart>,\n\t\t{ lineItemId, quantity }: CartRemoveLineItemAction,\n\t) {\n\t\tconst lineItem = resource.lineItems.find((x) => x.id === lineItemId);\n\t\tif (!lineItem) {\n\t\t\t// Check if product is found\n\t\t\tthrow new CommercetoolsError<GeneralError>({\n\t\t\t\tcode: \"General\",\n\t\t\t\tmessage: `A line item with ID '${lineItemId}' not found.`,\n\t\t\t});\n\t\t}\n\n\t\tconst shouldDelete = !quantity || quantity >= lineItem.quantity;\n\t\tif (shouldDelete) {\n\t\t\t// delete line item\n\t\t\tresource.lineItems = resource.lineItems.filter(\n\t\t\t\t(x) => x.id !== lineItemId,\n\t\t\t);\n\t\t} else {\n\t\t\t// decrease quantity and update total price\n\t\t\tresource.lineItems.forEach((x) => {\n\t\t\t\tif (x.id === lineItemId && quantity) {\n\t\t\t\t\tx.quantity -= quantity;\n\t\t\t\t\tx.totalPrice.centAmount = calculateLineItemTotalPrice(x);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\t// Update cart total price\n\t\tresource.totalPrice.centAmount = calculateCartTotalPrice(resource);\n\t}\n\n\taddCustomLineItem(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Cart>,\n\t\t{\n\t\t\tmoney,\n\t\t\tname,\n\t\t\tslug,\n\t\t\tquantity = 1,\n\t\t\ttaxCategory,\n\t\t\tcustom,\n\t\t\tpriceMode = \"Standard\",\n\t\t\tkey,\n\t\t}: CartAddCustomLineItemAction,\n\t) {\n\t\tconst customLineItem = createCustomLineItemFromDraft(\n\t\t\tcontext.projectKey,\n\t\t\t{ money, name, slug, quantity, taxCategory, custom, priceMode, key },\n\t\t\tthis._storage,\n\t\t\tresource.shippingAddress?.country ?? resource.country,\n\t\t);\n\n\t\tresource.customLineItems.push(customLineItem);\n\t\tresource.totalPrice.centAmount = calculateCartTotalPrice(resource);\n\t}\n\n\tremoveCustomLineItem(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Cart>,\n\t\t{ customLineItemId, customLineItemKey }: CartRemoveCustomLineItemAction,\n\t) {\n\t\tlet customLineItem;\n\n\t\tif (!customLineItemId && !customLineItemKey) {\n\t\t\tthrow new CommercetoolsError<GeneralError>({\n\t\t\t\tcode: \"General\",\n\t\t\t\tmessage:\n\t\t\t\t\t\"Either customLineItemId or customLineItemKey needs to be provided.\",\n\t\t\t});\n\t\t}\n\n\t\tif (customLineItemId) {\n\t\t\tcustomLineItem = resource.customLineItems.find(\n\t\t\t\t(x) => x.id === customLineItemId,\n\t\t\t);\n\t\t\tif (!customLineItem) {\n\t\t\t\tthrow new CommercetoolsError<GeneralError>({\n\t\t\t\t\tcode: \"General\",\n\t\t\t\t\tmessage: `A custom line item with ID '${customLineItemId}' not found.`,\n\t\t\t\t});\n\t\t\t}\n\t\t\tresource.customLineItems = resource.customLineItems.filter(\n\t\t\t\t(x) => x.id !== customLineItemId,\n\t\t\t);\n\t\t}\n\n\t\tif (customLineItemKey) {\n\t\t\tcustomLineItem = resource.customLineItems.find(\n\t\t\t\t(x) => x.key === customLineItemKey,\n\t\t\t);\n\t\t\tif (!customLineItem) {\n\t\t\t\tthrow new CommercetoolsError<GeneralError>({\n\t\t\t\t\tcode: \"General\",\n\t\t\t\t\tmessage: `A custom line item with key '${customLineItemKey}' not found.`,\n\t\t\t\t});\n\t\t\t}\n\t\t\tresource.customLineItems = resource.customLineItems.filter(\n\t\t\t\t(x) => x.key !== customLineItemKey,\n\t\t\t);\n\t\t}\n\n\t\tresource.totalPrice.centAmount = calculateCartTotalPrice(resource);\n\t}\n\n\tchangeCustomLineItemQuantity(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Cart>,\n\t\t{\n\t\t\tcustomLineItemId,\n\t\t\tcustomLineItemKey,\n\t\t\tquantity,\n\t\t}: CartChangeCustomLineItemQuantityAction,\n\t) {\n\t\tlet customLineItem;\n\n\t\tif (!customLineItemId && !customLineItemKey) {\n\t\t\tthrow new CommercetoolsError<GeneralError>({\n\t\t\t\tcode: \"General\",\n\t\t\t\tmessage:\n\t\t\t\t\t\"Either customLineItemId or customLineItemKey needs to be provided.\",\n\t\t\t});\n\t\t}\n\n\t\tconst setQuantity = (\n\t\t\tcustomLineItem: Writable<CustomLineItem> | undefined,\n\t\t) => {\n\t\t\tif (!customLineItem) {\n\t\t\t\tthrow new CommercetoolsError<GeneralError>({\n\t\t\t\t\tcode: \"General\",\n\t\t\t\t\tmessage: `A custom line item with ${customLineItemId ? `ID '${customLineItemId}'` : `key '${customLineItemKey}'`} not found.`,\n\t\t\t\t});\n\t\t\t}\n\t\t\tcustomLineItem.quantity = quantity;\n\t\t\tcustomLineItem.totalPrice = createCentPrecisionMoney({\n\t\t\t\t...customLineItem.money,\n\t\t\t\tcentAmount: (customLineItem.money.centAmount ?? 0) * quantity,\n\t\t\t});\n\t\t};\n\n\t\tif (customLineItemId) {\n\t\t\tcustomLineItem = resource.customLineItems.find(\n\t\t\t\t(x) => x.id === customLineItemId,\n\t\t\t);\n\t\t\tsetQuantity(customLineItem);\n\t\t}\n\n\t\tif (customLineItemKey) {\n\t\t\tcustomLineItem = resource.customLineItems.find(\n\t\t\t\t(x) => x.key === customLineItemKey,\n\t\t\t);\n\t\t\tsetQuantity(customLineItem);\n\t\t}\n\n\t\t// Update cart total price\n\t\tresource.totalPrice.centAmount = calculateCartTotalPrice(resource);\n\t}\n\n\tchangeCustomLineItemMoney(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Cart>,\n\t\t{\n\t\t\tcustomLineItemId,\n\t\t\tcustomLineItemKey,\n\t\t\tmoney,\n\t\t}: CartChangeCustomLineItemMoneyAction,\n\t) {\n\t\tlet customLineItem;\n\n\t\tconst setMoney = (customLineItem: Writable<CustomLineItem> | undefined) => {\n\t\t\tif (!customLineItem) {\n\t\t\t\tthrow new CommercetoolsError<GeneralError>({\n\t\t\t\t\tcode: \"General\",\n\t\t\t\t\tmessage: `A custom line item with ${customLineItemId ? `ID '${customLineItemId}'` : `key '${customLineItemKey}'`} not found.`,\n\t\t\t\t});\n\t\t\t}\n\t\t\tcustomLineItem.money = createTypedMoney(money);\n\t\t\tcustomLineItem.totalPrice = createCentPrecisionMoney({\n\t\t\t\t...money,\n\t\t\t\tcentAmount: (money.centAmount ?? 0) * customLineItem.quantity,\n\t\t\t});\n\t\t};\n\n\t\tif (customLineItemId) {\n\t\t\tcustomLineItem = resource.customLineItems.find(\n\t\t\t\t(x) => x.id === customLineItemId,\n\t\t\t);\n\t\t\tsetMoney(customLineItem);\n\t\t}\n\n\t\tif (customLineItemKey) {\n\t\t\tcustomLineItem = resource.customLineItems.find(\n\t\t\t\t(x) => x.key === customLineItemKey,\n\t\t\t);\n\t\t\tsetMoney(customLineItem);\n\t\t}\n\n\t\t// Update cart total price\n\t\tresource.totalPrice.centAmount = calculateCartTotalPrice(resource);\n\t}\n\n\tsetAnonymousId(\n\t\t_context: RepositoryContext,\n\t\tresource: Writable<Cart>,\n\t\t{ anonymousId }: CartSetAnonymousIdAction,\n\t) {\n\t\tresource.anonymousId = anonymousId;\n\t\tresource.customerId = undefined;\n\t}\n\n\tsetBillingAddress(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Cart>,\n\t\t{ address }: CartSetBillingAddressAction,\n\t) {\n\t\tresource.billingAddress = createAddress(\n\t\t\taddress,\n\t\t\tcontext.projectKey,\n\t\t\tthis._storage,\n\t\t);\n\t}\n\n\tsetBillingAddressCustomType(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Cart>,\n\t\tcustom: CartSetBillingAddressCustomTypeAction,\n\t) {\n\t\tif (!resource.billingAddress) {\n\t\t\tthrow new Error(\"Resource has no billing address\");\n\t\t}\n\n\t\tif (!custom.type) {\n\t\t\tresource.billingAddress.custom = undefined;\n\t\t\treturn;\n\t\t}\n\n\t\tconst resolvedType = this._storage.getByResourceIdentifier<\"type\">(\n\t\t\tcontext.projectKey,\n\t\t\tcustom.type,\n\t\t);\n\n\t\tif (!resolvedType) {\n\t\t\tthrow new Error(`Type ${custom.type} not found`);\n\t\t}\n\n\t\tresource.billingAddress.custom = {\n\t\t\ttype: {\n\t\t\t\ttypeId: \"type\",\n\t\t\t\tid: resolvedType.id,\n\t\t\t},\n\t\t\tfields: custom.fields || {},\n\t\t};\n\t}\n\n\tsetCountry(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Cart>,\n\t\t{ country }: CartSetCountryAction,\n\t) {\n\t\tresource.country = country;\n\t}\n\n\tsetCustomerEmail(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Cart>,\n\t\t{ email }: CartSetCustomerEmailAction,\n\t) {\n\t\tresource.customerEmail = email;\n\t}\n\n\tsetCustomerId(\n\t\t_context: RepositoryContext,\n\t\tresource: Writable<Cart>,\n\t\t{ customerId }: CartSetCustomerIdAction,\n\t) {\n\t\tresource.anonymousId = undefined;\n\t\tresource.customerId = customerId;\n\t}\n\n\tsetCustomField(\n\t\tcontext: RepositoryContext,\n\t\tresource: Cart,\n\t\t{ name, value }: CartSetCustomFieldAction,\n\t) {\n\t\tif (!resource.custom) {\n\t\t\tthrow new Error(\"Resource has no custom field\");\n\t\t}\n\n\t\tresource.custom.fields[name] = value;\n\t}\n\n\tsetCustomShippingMethod(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Cart>,\n\t\t{\n\t\t\tshippingMethodName,\n\t\t\tshippingRate,\n\t\t\ttaxCategory,\n\t\t\texternalTaxRate,\n\t\t}: CartSetCustomShippingMethodAction,\n\t) {\n\t\tif (externalTaxRate) {\n\t\t\tthrow new Error(\"External tax rate is not supported\");\n\t\t}\n\n\t\tconst tax = taxCategory\n\t\t\t? this._storage.getByResourceIdentifier<\"tax-category\">(\n\t\t\t\t\tcontext.projectKey,\n\t\t\t\t\ttaxCategory,\n\t\t\t\t)\n\t\t\t: undefined;\n\n\t\tresource.shippingInfo = {\n\t\t\tshippingMethodName,\n\t\t\tprice: createCentPrecisionMoney(shippingRate.price),\n\t\t\tshippingRate: {\n\t\t\t\tprice: createTypedMoney(shippingRate.price),\n\t\t\t\ttiers: [],\n\t\t\t},\n\t\t\ttaxCategory: tax\n\t\t\t\t? {\n\t\t\t\t\t\ttypeId: \"tax-category\",\n\t\t\t\t\t\tid: tax?.id,\n\t\t\t\t\t}\n\t\t\t\t: undefined,\n\t\t\tshippingMethodState: \"MatchesCart\",\n\t\t};\n\t}\n\n\tsetCustomType(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Cart>,\n\t\t{ type, fields }: CartSetCustomTypeAction,\n\t) {\n\t\tif (!type) {\n\t\t\tresource.custom = undefined;\n\t\t} else {\n\t\t\tconst resolvedType = this._storage.getByResourceIdentifier(\n\t\t\t\tcontext.projectKey,\n\t\t\t\ttype,\n\t\t\t);\n\t\t\tif (!resolvedType) {\n\t\t\t\tthrow new Error(`Type ${type} not found`);\n\t\t\t}\n\n\t\t\tresource.custom = {\n\t\t\t\ttype: {\n\t\t\t\t\ttypeId: \"type\",\n\t\t\t\t\tid: resolvedType.id,\n\t\t\t\t},\n\t\t\t\tfields: fields || {},\n\t\t\t};\n\t\t}\n\t}\n\n\tsetDirectDiscounts(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Cart>,\n\t\t{ discounts }: CartSetDirectDiscountsAction,\n\t) {\n\t\t// Doesn't apply any discounts logic, just sets the directDiscounts field\n\t\tresource.directDiscounts = discounts.map(\n\t\t\t(discount) =>\n\t\t\t\t({\n\t\t\t\t\t...discount,\n\t\t\t\t\tid: uuidv4(),\n\t\t\t\t}) as DirectDiscount,\n\t\t);\n\t}\n\n\tsetLineItemCustomField(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Cart>,\n\t\t{\n\t\t\tlineItemId,\n\t\t\tlineItemKey,\n\t\t\tname,\n\t\t\tvalue,\n\t\t\taction,\n\t\t}: CartSetLineItemCustomFieldAction,\n\t) {\n\t\tconst lineItem = resource.lineItems.find(\n\t\t\t(x) =>\n\t\t\t\t(lineItemId && x.id === lineItemId) ||\n\t\t\t\t(lineItemKey && x.key === lineItemKey),\n\t\t);\n\n\t\tif (!lineItem) {\n\t\t\t// Check if line item is found\n\t\t\tthrow new CommercetoolsError<GeneralError>({\n\t\t\t\tcode: \"General\",\n\t\t\t\tmessage: lineItemKey\n\t\t\t\t\t? `A line item with key '${lineItemKey}' not found.`\n\t\t\t\t\t: `A line item with ID '${lineItemId}' not found.`,\n\t\t\t});\n\t\t}\n\n\t\tif (!lineItem.custom) {\n\t\t\tthrow new Error(\"Resource has no custom field\");\n\t\t}\n\n\t\tlineItem.custom.fields[name] = value;\n\t}\n\n\tsetLineItemCustomType(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Cart>,\n\t\t{ lineItemId, lineItemKey, type, fields }: CartSetLineItemCustomTypeAction,\n\t) {\n\t\tconst lineItem = resource.lineItems.find(\n\t\t\t(x) =>\n\t\t\t\t(lineItemId && x.id === lineItemId) ||\n\t\t\t\t(lineItemKey && x.key === lineItemKey),\n\t\t);\n\n\t\tif (!lineItem) {\n\t\t\t// Check if line item is found\n\t\t\tthrow new CommercetoolsError<GeneralError>({\n\t\t\t\tcode: \"General\",\n\t\t\t\tmessage: lineItemKey\n\t\t\t\t\t? `A line item with key '${lineItemKey}' not found.`\n\t\t\t\t\t: `A line item with ID '${lineItemId}' not found.`,\n\t\t\t});\n\t\t}\n\n\t\tif (!type) {\n\t\t\tlineItem.custom = undefined;\n\t\t} else {\n\t\t\tconst resolvedType = this._storage.getByResourceIdentifier(\n\t\t\t\tcontext.projectKey,\n\t\t\t\ttype,\n\t\t\t);\n\t\t\tif (!resolvedType) {\n\t\t\t\tthrow new Error(`Type ${type} not found`);\n\t\t\t}\n\n\t\t\tlineItem.custom = {\n\t\t\t\ttype: {\n\t\t\t\t\ttypeId: \"type\",\n\t\t\t\t\tid: resolvedType.id,\n\t\t\t\t},\n\t\t\t\tfields: fields || {},\n\t\t\t};\n\t\t}\n\t}\n\n\tsetLineItemPrice(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Cart>,\n\t\t{ lineItemId, lineItemKey, externalPrice }: CartSetLineItemPriceAction,\n\t) {\n\t\tconst lineItem = resource.lineItems.find(\n\t\t\t(x) =>\n\t\t\t\t(lineItemId && x.id === lineItemId) ||\n\t\t\t\t(lineItemKey && x.key === lineItemKey),\n\t\t);\n\n\t\tif (!lineItem) {\n\t\t\tthrow new CommercetoolsError<GeneralError>({\n\t\t\t\tcode: \"General\",\n\t\t\t\tmessage: lineItemKey\n\t\t\t\t\t? `A line item with key '${lineItemKey}' not found.`\n\t\t\t\t\t: `A line item with ID '${lineItemId}' not found.`,\n\t\t\t});\n\t\t}\n\n\t\tif (!externalPrice && lineItem.priceMode !== \"ExternalPrice\") {\n\t\t\treturn;\n\t\t}\n\n\t\tif (\n\t\t\texternalPrice &&\n\t\t\texternalPrice.currencyCode !== resource.totalPrice.currencyCode\n\t\t) {\n\t\t\tthrow new CommercetoolsError<GeneralError>({\n\t\t\t\tcode: \"General\",\n\t\t\t\tmessage: `Currency mismatch. Expected '${resource.totalPrice.currencyCode}' but got '${externalPrice.currencyCode}'.`,\n\t\t\t});\n\t\t}\n\n\t\tif (externalPrice) {\n\t\t\tlineItem.priceMode = \"ExternalPrice\";\n\t\t\tconst priceValue = createTypedMoney(externalPrice);\n\n\t\t\tlineItem.price = lineItem.price ?? { id: uuidv4() };\n\t\t\tlineItem.price.value = priceValue;\n\t\t} else {\n\t\t\tlineItem.priceMode = \"Platform\";\n\n\t\t\tconst price = selectPrice({\n\t\t\t\tprices: lineItem.variant.prices,\n\t\t\t\tcurrency: resource.totalPrice.currencyCode,\n\t\t\t\tcountry: resource.country,\n\t\t\t});\n\n\t\t\tif (!price) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`No valid price found for ${lineItem.productId} for country ${resource.country} and currency ${resource.totalPrice.currencyCode}`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tlineItem.price = price;\n\t\t}\n\n\t\tconst lineItemTotal = calculateLineItemTotalPrice(lineItem);\n\t\tlineItem.totalPrice = createCentPrecisionMoney({\n\t\t\t...lineItem.price!.value,\n\t\t\tcentAmount: lineItemTotal,\n\t\t});\n\t\tresource.totalPrice.centAmount = calculateCartTotalPrice(resource);\n\t}\n\n\tsetLineItemShippingDetails(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Cart>,\n\t\t{\n\t\t\taction,\n\t\t\tshippingDetails,\n\t\t\tlineItemId,\n\t\t\tlineItemKey,\n\t\t}: CartSetLineItemShippingDetailsAction,\n\t) {\n\t\tconst lineItem = resource.lineItems.find(\n\t\t\t(x) =>\n\t\t\t\t(lineItemId && x.id === lineItemId) ||\n\t\t\t\t(lineItemKey && x.key === lineItemKey),\n\t\t);\n\n\t\tif (!lineItem) {\n\t\t\t// Check if line item is found\n\t\t\tthrow new CommercetoolsError<GeneralError>({\n\t\t\t\tcode: \"General\",\n\t\t\t\tmessage: lineItemKey\n\t\t\t\t\t? `A line item with key '${lineItemKey}' not found.`\n\t\t\t\t\t: `A line item with ID '${lineItemId}' not found.`,\n\t\t\t});\n\t\t}\n\n\t\tlineItem.shippingDetails = {\n\t\t\t...shippingDetails,\n\t\t\tvalid: true,\n\t\t} as ItemShippingDetails;\n\t}\n\n\tsetLocale(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Cart>,\n\t\t{ locale }: CartSetLocaleAction,\n\t) {\n\t\tresource.locale = locale;\n\t}\n\n\tsetShippingAddress(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Cart>,\n\t\t{ address }: CartSetShippingAddressAction,\n\t) {\n\t\tif (!address) {\n\t\t\tresource.shippingAddress = undefined;\n\t\t\treturn;\n\t\t}\n\n\t\tlet custom: CustomFields | undefined;\n\t\tif ((address as Address & AddressDraft).custom) {\n\t\t\tcustom = createCustomFields(\n\t\t\t\t(address as Address & AddressDraft).custom,\n\t\t\t\tcontext.projectKey,\n\t\t\t\tthis._storage,\n\t\t\t);\n\t\t}\n\n\t\tresource.shippingAddress = {\n\t\t\t...address,\n\t\t\tcustom: custom,\n\t\t};\n\t}\n\n\tsetShippingAddressCustomType(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Cart>,\n\t\tcustom: CartSetShippingAddressCustomTypeAction,\n\t) {\n\t\tif (!resource.shippingAddress) {\n\t\t\tthrow new Error(\"Resource has no shipping address\");\n\t\t}\n\n\t\tif (!custom.type) {\n\t\t\tresource.shippingAddress.custom = undefined;\n\t\t\treturn;\n\t\t}\n\n\t\tconst resolvedType = this._storage.getByResourceIdentifier<\"type\">(\n\t\t\tcontext.projectKey,\n\t\t\tcustom.type,\n\t\t);\n\n\t\tif (!resolvedType) {\n\t\t\tthrow new Error(`Type ${custom.type} not found`);\n\t\t}\n\n\t\tresource.shippingAddress.custom = {\n\t\t\ttype: {\n\t\t\t\ttypeId: \"type\",\n\t\t\t\tid: resolvedType.id,\n\t\t\t},\n\t\t\tfields: custom.fields || {},\n\t\t};\n\t}\n\n\tsetShippingMethod(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Cart>,\n\t\t{ shippingMethod }: CartSetShippingMethodAction,\n\t) {\n\t\tif (shippingMethod) {\n\t\t\tresource.shippingInfo = this.repository.createShippingInfo(\n\t\t\t\tcontext,\n\t\t\t\tresource,\n\t\t\t\tshippingMethod,\n\t\t\t);\n\t\t} else {\n\t\t\tresource.shippingInfo = undefined;\n\t\t}\n\t}\n\n\tsetShippingAddressCustomField(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Cart>,\n\t\t{ name, value }: CartSetShippingAddressCustomFieldAction,\n\t) {\n\t\tif (!resource.shippingAddress) {\n\t\t\tthrow new Error(\"Resource has no shipping address\");\n\t\t}\n\t\tif (!resource.shippingAddress.custom) {\n\t\t\tthrow new Error(\"Resource has no custom field\");\n\t\t}\n\t\tresource.shippingAddress.custom.fields[name] = value;\n\t}\n\n\tremoveShippingMethod(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Cart>,\n\t\t{ shippingKey }: CartRemoveShippingMethodAction,\n\t) {\n\t\tif (!resource.shippingInfo) {\n\t\t\treturn;\n\t\t}\n\t\tconst shippingMethod =\n\t\t\tthis._storage.getByResourceIdentifier<\"shipping-method\">(\n\t\t\t\tcontext.projectKey,\n\t\t\t\t{\n\t\t\t\t\ttypeId: \"shipping-method\",\n\t\t\t\t\tkey: shippingKey,\n\t\t\t\t} as ShippingMethodResourceIdentifier,\n\t\t\t);\n\n\t\tif (resource.shippingInfo?.shippingMethod?.id !== shippingMethod.id) {\n\t\t\tthrow new Error(\"Shipping method with key not found\");\n\t\t}\n\n\t\tresource.shippingInfo = undefined;\n\t}\n}\n","import type {\n\tBusinessUnit,\n\tCart,\n\tCartDraft,\n\tGeneralError,\n\tInvalidOperationError,\n\tLineItem,\n\tLineItemDraft,\n\tProduct,\n\tProductPagedQueryResponse,\n\tShippingMethodDoesNotMatchCartError,\n} from \"@commercetools/platform-sdk\";\nimport { v4 as uuidv4 } from \"uuid\";\nimport type { Config } from \"#src/config.ts\";\nimport { CommercetoolsError } from \"#src/exceptions.ts\";\nimport { getBaseResourceProperties } from \"#src/helpers.ts\";\nimport { calculateTaxTotals } from \"#src/lib/tax.ts\";\nimport {\n\tcreateShippingInfoFromMethod,\n\tgetShippingMethodsMatchingCart,\n} from \"#src/shipping.ts\";\nimport type { Writable } from \"#src/types.ts\";\nimport {\n\tAbstractResourceRepository,\n\ttype RepositoryContext,\n} from \"../abstract.ts\";\nimport { createAddress, createCustomFields } from \"../helpers.ts\";\nimport { CartUpdateHandler } from \"./actions.ts\";\nimport {\n\tcalculateCartTotalPrice,\n\tcreateCustomLineItemFromDraft,\n\tselectPrice,\n} from \"./helpers.ts\";\n\nexport class CartRepository extends AbstractResourceRepository<\"cart\"> {\n\tconstructor(config: Config) {\n\t\tsuper(\"cart\", config);\n\t\tthis.actions = new CartUpdateHandler(this._storage, this);\n\t}\n\n\tcreate(context: RepositoryContext, draft: CartDraft): Cart {\n\t\tif (draft.anonymousId && draft.customerId) {\n\t\t\tthrow new CommercetoolsError<InvalidOperationError>({\n\t\t\t\tcode: \"InvalidOperation\",\n\t\t\t\tmessage: \"Can set only one of customer OR anonymousId\",\n\t\t\t});\n\t\t}\n\n\t\t// Validate that the customer exists\n\t\tif (draft.customerId) {\n\t\t\tthis._storage.getByResourceIdentifier(context.projectKey, {\n\t\t\t\ttypeId: \"customer\",\n\t\t\t\tid: draft.customerId,\n\t\t\t});\n\t\t}\n\n\t\tlet storedBusinessUnit: BusinessUnit | undefined;\n\t\tif (draft.businessUnit?.id || draft.businessUnit?.key) {\n\t\t\tstoredBusinessUnit =\n\t\t\t\tthis._storage.getByResourceIdentifier<\"business-unit\">(\n\t\t\t\t\tcontext.projectKey,\n\t\t\t\t\t{\n\t\t\t\t\t\ttypeId: \"business-unit\",\n\t\t\t\t\t\tid: draft.businessUnit.id,\n\t\t\t\t\t\tkey: draft.businessUnit.key,\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t}\n\n\t\tconst lineItems =\n\t\t\tdraft.lineItems?.map((draftLineItem) =>\n\t\t\t\tthis.draftLineItemtoLineItem(\n\t\t\t\t\tcontext.projectKey,\n\t\t\t\t\tdraftLineItem,\n\t\t\t\t\tdraft.currency,\n\t\t\t\t\tdraft.country,\n\t\t\t\t),\n\t\t\t) ?? [];\n\n\t\tconst customLineItems =\n\t\t\tdraft.customLineItems?.map((draftCustomLineItem) =>\n\t\t\t\tcreateCustomLineItemFromDraft(\n\t\t\t\t\tcontext.projectKey,\n\t\t\t\t\tdraftCustomLineItem,\n\t\t\t\t\tthis._storage,\n\t\t\t\t\tdraft.shippingAddress?.country ?? draft.country,\n\t\t\t\t),\n\t\t\t) ?? [];\n\n\t\tconst resource: Writable<Cart> = {\n\t\t\t...getBaseResourceProperties(),\n\t\t\tanonymousId: draft.anonymousId,\n\t\t\tbusinessUnit:\n\t\t\t\tstoredBusinessUnit && draft.businessUnit\n\t\t\t\t\t? {\n\t\t\t\t\t\t\ttypeId: draft.businessUnit.typeId,\n\t\t\t\t\t\t\tkey: storedBusinessUnit.key,\n\t\t\t\t\t\t}\n\t\t\t\t\t: undefined,\n\t\t\tbillingAddress: draft.billingAddress\n\t\t\t\t? createAddress(draft.billingAddress, context.projectKey, this._storage)\n\t\t\t\t: undefined,\n\t\t\tcartState: \"Active\",\n\t\t\tcountry: draft.country,\n\t\t\tcustomerId: draft.customerId,\n\t\t\tcustomerEmail: draft.customerEmail,\n\t\t\tcustomLineItems,\n\t\t\tdirectDiscounts: [],\n\t\t\tdiscountCodes: [],\n\t\t\tinventoryMode: \"None\",\n\t\t\titemShippingAddresses: [],\n\t\t\tlineItems,\n\t\t\tlocale: draft.locale,\n\t\t\tpriceRoundingMode: draft.priceRoundingMode ?? \"HalfEven\",\n\t\t\ttaxCalculationMode: draft.taxCalculationMode ?? \"LineItemLevel\",\n\t\t\ttaxMode: draft.taxMode ?? \"Platform\",\n\t\t\ttaxRoundingMode: draft.taxRoundingMode ?? \"HalfEven\",\n\t\t\ttotalPrice: {\n\t\t\t\ttype: \"centPrecision\",\n\t\t\t\tcentAmount: 0,\n\t\t\t\tcurrencyCode: draft.currency,\n\t\t\t\tfractionDigits: 0,\n\t\t\t},\n\t\t\tshippingMode: \"Single\",\n\t\t\tshippingAddress: draft.shippingAddress\n\t\t\t\t? createAddress(\n\t\t\t\t\t\tdraft.shippingAddress,\n\t\t\t\t\t\tcontext.projectKey,\n\t\t\t\t\t\tthis._storage,\n\t\t\t\t\t)\n\t\t\t\t: undefined,\n\t\t\tshipping: [],\n\t\t\tshippingInfo: undefined,\n\t\t\torigin: draft.origin ?? \"Customer\",\n\t\t\trefusedGifts: [],\n\t\t\tcustom: createCustomFields(\n\t\t\t\tdraft.custom,\n\t\t\t\tcontext.projectKey,\n\t\t\t\tthis._storage,\n\t\t\t),\n\t\t};\n\t\tresource.totalPrice.centAmount = calculateCartTotalPrice(resource);\n\t\tresource.store = context.storeKey\n\t\t\t? { typeId: \"store\", key: context.storeKey }\n\t\t\t: draft.store?.key\n\t\t\t\t? { typeId: \"store\", key: draft.store.key }\n\t\t\t\t: undefined;\n\n\t\t// Set shipping info after resource is created\n\t\tif (draft.shippingMethod) {\n\t\t\tresource.shippingInfo = this.createShippingInfo(\n\t\t\t\tcontext,\n\t\t\t\tresource,\n\t\t\t\tdraft.shippingMethod,\n\t\t\t);\n\t\t}\n\n\t\tconst { taxedPrice, taxedShippingPrice } = calculateTaxTotals(resource);\n\t\tresource.taxedPrice = taxedPrice;\n\t\tresource.taxedShippingPrice = taxedShippingPrice;\n\n\t\treturn this.saveNew(context, resource);\n\t}\n\n\tgetActiveCart(projectKey: string): Cart | undefined {\n\t\t// Get first active cart\n\t\tconst results = this._storage.query(projectKey, this.getTypeId(), {\n\t\t\twhere: [`cartState=\"Active\"`],\n\t\t});\n\t\tif (results.count > 0) {\n\t\t\treturn results.results[0] as Cart;\n\t\t}\n\n\t\treturn;\n\t}\n\n\tdraftLineItemtoLineItem = (\n\t\tprojectKey: string,\n\t\tdraftLineItem: LineItemDraft,\n\t\tcurrency: string,\n\t\tcountry: string | undefined,\n\t): LineItem => {\n\t\tconst { productId, quantity, variantId, sku } = draftLineItem;\n\n\t\tlet product: Product | null = null;\n\n\t\tif (productId && variantId) {\n\t\t\t// Fetch product and variant by ID\n\t\t\tproduct = this._storage.get(projectKey, \"product\", productId, {});\n\t\t} else if (sku) {\n\t\t\t// Fetch product and variant by SKU\n\t\t\tconst items = this._storage.query(projectKey, \"product\", {\n\t\t\t\twhere: [\n\t\t\t\t\t`masterData(current(masterVariant(sku=\"${sku}\"))) or masterData(current(variants(sku=\"${sku}\")))`,\n\t\t\t\t],\n\t\t\t}) as ProductPagedQueryResponse;\n\n\t\t\tif (items.count === 1) {\n\t\t\t\tproduct = items.results[0];\n\t\t\t}\n\t\t}\n\n\t\tif (!product) {\n\t\t\t// Check if product is found\n\t\t\tthrow new CommercetoolsError<GeneralError>({\n\t\t\t\tcode: \"General\",\n\t\t\t\tmessage: sku\n\t\t\t\t\t? `A product containing a variant with SKU '${sku}' not found.`\n\t\t\t\t\t: `A product with ID '${productId}' not found.`,\n\t\t\t});\n\t\t}\n\n\t\t// Find matching variant\n\t\tconst variant = [\n\t\t\tproduct.masterData.current.masterVariant,\n\t\t\t...product.masterData.current.variants,\n\t\t].find((x) => {\n\t\t\tif (sku) return x.sku === sku;\n\t\t\tif (variantId) return x.id === variantId;\n\t\t\treturn false;\n\t\t});\n\n\t\tif (!variant) {\n\t\t\t// Check if variant is found\n\t\t\tthrow new Error(\n\t\t\t\tsku\n\t\t\t\t\t? `A variant with SKU '${sku}' for product '${product.id}' not found.`\n\t\t\t\t\t: `A variant with ID '${variantId}' for product '${product.id}' not found.`,\n\t\t\t);\n\t\t}\n\n\t\tconst quant = quantity ?? 1;\n\n\t\tconst price = selectPrice({ prices: variant.prices, currency, country });\n\t\tif (!price) {\n\t\t\tthrow new Error(\n\t\t\t\t`No valid price found for ${productId} for country ${country} and currency ${currency}`,\n\t\t\t);\n\t\t}\n\n\t\treturn {\n\t\t\tid: uuidv4(),\n\t\t\tproductId: product.id,\n\t\t\tproductKey: product.key,\n\t\t\tproductSlug: product.masterData.current.slug,\n\t\t\tproductType: product.productType,\n\t\t\tname: product.masterData.current.name,\n\t\t\tvariant,\n\t\t\tprice: price,\n\t\t\ttotalPrice: {\n\t\t\t\ttype: \"centPrecision\",\n\t\t\t\tcurrencyCode: price.value.currencyCode,\n\t\t\t\tfractionDigits: price.value.fractionDigits,\n\t\t\t\tcentAmount: price.value.centAmount * quant,\n\t\t\t},\n\t\t\ttaxedPricePortions: [],\n\t\t\tperMethodTaxRate: [],\n\t\t\tquantity: quant,\n\t\t\tdiscountedPricePerQuantity: [],\n\t\t\tlineItemMode: \"Standard\",\n\t\t\tpriceMode: \"Platform\",\n\t\t\tstate: [],\n\t\t\tcustom: createCustomFields(\n\t\t\t\tdraftLineItem.custom,\n\t\t\t\tprojectKey,\n\t\t\t\tthis._storage,\n\t\t\t),\n\t\t};\n\t};\n\n\tcreateShippingInfo(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Cart>,\n\t\tshippingMethodRef: NonNullable<CartDraft[\"shippingMethod\"]>,\n\t): NonNullable<Cart[\"shippingInfo\"]> {\n\t\tif (resource.taxMode === \"External\") {\n\t\t\tthrow new Error(\"External tax rate is not supported\");\n\t\t}\n\n\t\t// Bit of a hack: calling this checks that the resource identifier is\n\t\t// valid (i.e. id xor key) and that the shipping method exists.\n\t\tthis._storage.getByResourceIdentifier<\"shipping-method\">(\n\t\t\tcontext.projectKey,\n\t\t\tshippingMethodRef,\n\t\t);\n\n\t\t// getShippingMethodsMatchingCart does the work of determining whether the\n\t\t// shipping method is allowed for the cart, and which shipping rate to use\n\t\tconst shippingMethods = getShippingMethodsMatchingCart(\n\t\t\tcontext,\n\t\t\tthis._storage,\n\t\t\tresource,\n\t\t\t{\n\t\t\t\texpand: [\"zoneRates[*].zone\"],\n\t\t\t},\n\t\t);\n\n\t\tconst method = shippingMethods.results.find((candidate) =>\n\t\t\tshippingMethodRef.id\n\t\t\t\t? candidate.id === shippingMethodRef.id\n\t\t\t\t: candidate.key === shippingMethodRef.key,\n\t\t);\n\n\t\t// Not finding the method in the results means it's not allowed, since\n\t\t// getShippingMethodsMatchingCart only returns allowed methods and we\n\t\t// already checked that the method exists.\n\t\tif (!method) {\n\t\t\tthrow new CommercetoolsError<ShippingMethodDoesNotMatchCartError>({\n\t\t\t\tcode: \"ShippingMethodDoesNotMatchCart\",\n\t\t\t\tmessage: `The shipping method with ${shippingMethodRef.id ? `ID '${shippingMethodRef.id}'` : `key '${shippingMethodRef.key}'`} is not allowed for the cart with ID '${resource.id}'.`,\n\t\t\t});\n\t\t}\n\n\t\t// Use the shared shipping info creation logic\n\t\treturn createShippingInfoFromMethod(\n\t\t\tcontext,\n\t\t\tthis._storage,\n\t\t\tresource,\n\t\t\tmethod,\n\t\t);\n\t}\n}\n","import type {\n\tCustomLineItemReturnItem,\n\tGeneralError,\n\tLineItemReturnItem,\n\tOrder,\n\tOrderAddPaymentAction,\n\tOrderAddReturnInfoAction,\n\tOrderChangeOrderStateAction,\n\tOrderChangePaymentStateAction,\n\tOrderChangeShipmentStateAction,\n\tOrderSetBillingAddressAction,\n\tOrderSetCustomerEmailAction,\n\tOrderSetCustomerIdAction,\n\tOrderSetCustomFieldAction,\n\tOrderSetCustomTypeAction,\n\tOrderSetDeliveryCustomFieldAction,\n\tOrderSetLineItemCustomFieldAction,\n\tOrderSetLineItemCustomTypeAction,\n\tOrderSetLocaleAction,\n\tOrderSetOrderNumberAction,\n\tOrderSetParcelCustomFieldAction,\n\tOrderSetPurchaseOrderNumberAction,\n\tOrderSetShippingAddressAction,\n\tOrderSetStoreAction,\n\tOrderTransitionStateAction,\n\tOrderUpdateAction,\n\tOrderUpdateSyncInfoAction,\n\tReturnInfo,\n\tState,\n\tStore,\n\tSyncInfo,\n} from \"@commercetools/platform-sdk\";\nimport { CommercetoolsError } from \"#src/exceptions.ts\";\nimport { getBaseResourceProperties } from \"#src/helpers.ts\";\nimport type { Writable } from \"#src/types.ts\";\nimport type { RepositoryContext, UpdateHandlerInterface } from \"../abstract.ts\";\nimport { AbstractUpdateHandler } from \"../abstract.ts\";\nimport { createAddress } from \"../helpers.ts\";\n\nexport class OrderUpdateHandler\n\textends AbstractUpdateHandler\n\timplements Partial<UpdateHandlerInterface<Order, OrderUpdateAction>>\n{\n\taddPayment(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Order>,\n\t\t{ payment }: OrderAddPaymentAction,\n\t) {\n\t\tconst resolvedPayment = this._storage.getByResourceIdentifier(\n\t\t\tcontext.projectKey,\n\t\t\tpayment,\n\t\t);\n\t\tif (!resolvedPayment) {\n\t\t\tthrow new Error(`Payment ${payment.id} not found`);\n\t\t}\n\n\t\tif (!resource.paymentInfo) {\n\t\t\tresource.paymentInfo = {\n\t\t\t\tpayments: [],\n\t\t\t};\n\t\t}\n\n\t\tresource.paymentInfo.payments.push({\n\t\t\ttypeId: \"payment\",\n\t\t\tid: payment.id!,\n\t\t});\n\t}\n\n\taddReturnInfo(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Order>,\n\t\tinfo: OrderAddReturnInfoAction,\n\t) {\n\t\tif (!resource.returnInfo) {\n\t\t\tresource.returnInfo = [];\n\t\t}\n\n\t\tconst resolved: ReturnInfo = {\n\t\t\titems: info.items.map((item) => {\n\t\t\t\tconst common = {\n\t\t\t\t\t...getBaseResourceProperties(),\n\t\t\t\t\tquantity: item.quantity,\n\t\t\t\t\tpaymentState: \"Initial\",\n\t\t\t\t\tshipmentState: \"Initial\",\n\t\t\t\t\tcomment: item.comment,\n\t\t\t\t};\n\t\t\t\tif (item.customLineItemId) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\t...common,\n\t\t\t\t\t\ttype: \"CustomLineItemReturnItem\",\n\t\t\t\t\t\tcustomLineItemId: item.customLineItemId,\n\t\t\t\t\t} as CustomLineItemReturnItem;\n\t\t\t\t}\n\t\t\t\treturn {\n\t\t\t\t\t...common,\n\t\t\t\t\ttype: \"LineItemReturnItem\",\n\t\t\t\t\tlineItemId: item.customLineItemId || item.lineItemId,\n\t\t\t\t} as LineItemReturnItem;\n\t\t\t}),\n\t\t\treturnTrackingId: info.returnTrackingId,\n\t\t\treturnDate: info.returnDate,\n\t\t};\n\n\t\tresource.returnInfo.push(resolved);\n\t}\n\n\tchangeOrderState(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Order>,\n\t\t{ orderState }: OrderChangeOrderStateAction,\n\t) {\n\t\tresource.orderState = orderState;\n\t}\n\n\tchangePaymentState(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Order>,\n\t\t{ paymentState }: OrderChangePaymentStateAction,\n\t) {\n\t\tresource.paymentState = paymentState;\n\t}\n\n\tchangeShipmentState(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Order>,\n\t\t{ shipmentState }: OrderChangeShipmentStateAction,\n\t) {\n\t\tresource.shipmentState = shipmentState;\n\t}\n\n\tsetBillingAddress(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Order>,\n\t\t{ address }: OrderSetBillingAddressAction,\n\t) {\n\t\tresource.billingAddress = createAddress(\n\t\t\taddress,\n\t\t\tcontext.projectKey,\n\t\t\tthis._storage,\n\t\t);\n\t}\n\n\tsetCustomerEmail(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Order>,\n\t\t{ email }: OrderSetCustomerEmailAction,\n\t) {\n\t\tresource.customerEmail = email;\n\t}\n\n\tsetCustomerId(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Order>,\n\t\t{ customerId }: OrderSetCustomerIdAction,\n\t) {\n\t\tresource.customerId = customerId;\n\t}\n\n\tsetCustomField(\n\t\tcontext: RepositoryContext,\n\t\tresource: Order,\n\t\t{ name, value }: OrderSetCustomFieldAction,\n\t) {\n\t\tif (!resource.custom) {\n\t\t\tthrow new Error(\"Resource has no custom field\");\n\t\t}\n\t\tresource.custom.fields[name] = value;\n\t}\n\n\tsetCustomType(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Order>,\n\t\t{ type, fields }: OrderSetCustomTypeAction,\n\t) {\n\t\tif (!type) {\n\t\t\tresource.custom = undefined;\n\t\t} else {\n\t\t\tconst resolvedType = this._storage.getByResourceIdentifier(\n\t\t\t\tcontext.projectKey,\n\t\t\t\ttype,\n\t\t\t);\n\t\t\tif (!resolvedType) {\n\t\t\t\tthrow new Error(`Type ${type} not found`);\n\t\t\t}\n\n\t\t\tresource.custom = {\n\t\t\t\ttype: {\n\t\t\t\t\ttypeId: \"type\",\n\t\t\t\t\tid: resolvedType.id,\n\t\t\t\t},\n\t\t\t\tfields: fields || {},\n\t\t\t};\n\t\t}\n\t}\n\n\tsetDeliveryCustomField(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Order>,\n\t\t{ deliveryId, name, value }: OrderSetDeliveryCustomFieldAction,\n\t) {\n\t\tif (!resource.shippingInfo) {\n\t\t\tthrow new Error(\"Resource has no shipping info\");\n\t\t}\n\n\t\tfor (const delivery of resource.shippingInfo.deliveries || []) {\n\t\t\tif (delivery.id === deliveryId && delivery.custom?.fields) {\n\t\t\t\tdelivery.custom.fields[name] = value;\n\t\t\t}\n\t\t}\n\t}\n\n\tsetLineItemCustomField(\n\t\tcontext: RepositoryContext,\n\t\tresource: Order,\n\t\t{\n\t\t\tlineItemId,\n\t\t\tlineItemKey,\n\t\t\tname,\n\t\t\tvalue,\n\t\t\taction,\n\t\t}: OrderSetLineItemCustomFieldAction,\n\t) {\n\t\tconst lineItem = resource.lineItems.find(\n\t\t\t(x) =>\n\t\t\t\t(lineItemId && x.id === lineItemId) ||\n\t\t\t\t(lineItemKey && x.key === lineItemKey),\n\t\t);\n\n\t\tif (!lineItem) {\n\t\t\t// Check if line item is found\n\t\t\tthrow new CommercetoolsError<GeneralError>({\n\t\t\t\tcode: \"General\",\n\t\t\t\tmessage: lineItemKey\n\t\t\t\t\t? `A line item with key '${lineItemKey}' not found.`\n\t\t\t\t\t: `A line item with ID '${lineItemId}' not found.`,\n\t\t\t});\n\t\t}\n\n\t\tif (!lineItem.custom) {\n\t\t\tthrow new Error(\"Resource has no custom field\");\n\t\t}\n\n\t\tlineItem.custom.fields[name] = value;\n\t}\n\n\tsetLineItemCustomType(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Order>,\n\t\t{ lineItemId, lineItemKey, type, fields }: OrderSetLineItemCustomTypeAction,\n\t) {\n\t\tconst lineItem = resource.lineItems.find(\n\t\t\t(x) =>\n\t\t\t\t(lineItemId && x.id === lineItemId) ||\n\t\t\t\t(lineItemKey && x.key === lineItemKey),\n\t\t);\n\n\t\tif (!lineItem) {\n\t\t\t// Check if line item is found\n\t\t\tthrow new CommercetoolsError<GeneralError>({\n\t\t\t\tcode: \"General\",\n\t\t\t\tmessage: lineItemKey\n\t\t\t\t\t? `A line item with key '${lineItemKey}' not found.`\n\t\t\t\t\t: `A line item with ID '${lineItemId}' not found.`,\n\t\t\t});\n\t\t}\n\n\t\tif (!type) {\n\t\t\tlineItem.custom = undefined;\n\t\t} else {\n\t\t\tconst resolvedType = this._storage.getByResourceIdentifier(\n\t\t\t\tcontext.projectKey,\n\t\t\t\ttype,\n\t\t\t);\n\t\t\tif (!resolvedType) {\n\t\t\t\tthrow new Error(`Type ${type} not found`);\n\t\t\t}\n\n\t\t\tlineItem.custom = {\n\t\t\t\ttype: {\n\t\t\t\t\ttypeId: \"type\",\n\t\t\t\t\tid: resolvedType.id,\n\t\t\t\t},\n\t\t\t\tfields: fields || {},\n\t\t\t};\n\t\t}\n\t}\n\n\tsetLocale(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Order>,\n\t\t{ locale }: OrderSetLocaleAction,\n\t) {\n\t\tresource.locale = locale;\n\t}\n\n\tsetOrderNumber(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Order>,\n\t\t{ orderNumber }: OrderSetOrderNumberAction,\n\t) {\n\t\tresource.orderNumber = orderNumber;\n\t}\n\n\tsetParcelCustomField(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Order>,\n\t\t{ parcelId, name, value }: OrderSetParcelCustomFieldAction,\n\t) {\n\t\tif (!resource.shippingInfo) {\n\t\t\tthrow new Error(\"Resource has no shipping info\");\n\t\t}\n\n\t\tfor (const delivery of resource.shippingInfo.deliveries || []) {\n\t\t\tfor (const parcel of delivery.parcels || []) {\n\t\t\t\tif (parcel.id === parcelId && parcel.custom?.fields) {\n\t\t\t\t\tparcel.custom.fields[name] = value;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tsetPurchaseOrderNumber(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Order>,\n\t\t{ purchaseOrderNumber }: OrderSetPurchaseOrderNumberAction,\n\t) {\n\t\tresource.purchaseOrderNumber = purchaseOrderNumber;\n\t}\n\n\tsetShippingAddress(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Order>,\n\t\t{ address }: OrderSetShippingAddressAction,\n\t) {\n\t\tresource.shippingAddress = createAddress(\n\t\t\taddress,\n\t\t\tcontext.projectKey,\n\t\t\tthis._storage,\n\t\t);\n\t}\n\n\tsetStore(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Order>,\n\t\t{ store }: OrderSetStoreAction,\n\t) {\n\t\tif (!store) return;\n\t\tconst resolvedType = this._storage.getByResourceIdentifier(\n\t\t\tcontext.projectKey,\n\t\t\tstore,\n\t\t);\n\t\tif (!resolvedType) {\n\t\t\tthrow new Error(`No store found with key=${store.key}`);\n\t\t}\n\n\t\tconst storeReference = resolvedType as Store;\n\t\tresource.store = {\n\t\t\ttypeId: \"store\",\n\t\t\tkey: storeReference.key,\n\t\t};\n\t}\n\n\ttransitionState(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Order>,\n\t\t{ state }: OrderTransitionStateAction,\n\t) {\n\t\tconst resolvedType = this._storage.getByResourceIdentifier(\n\t\t\tcontext.projectKey,\n\t\t\tstate,\n\t\t) as State | null;\n\n\t\tif (!resolvedType) {\n\t\t\tthrow new Error(\n\t\t\t\t`No state found with key=${state.key} or id=${state.key}`,\n\t\t\t);\n\t\t}\n\n\t\tresource.state = {\n\t\t\ttypeId: \"state\",\n\t\t\tid: resolvedType.id,\n\t\t\tobj: { ...resolvedType, key: state.key ?? \"\" },\n\t\t};\n\t}\n\n\tupdateSyncInfo(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Order>,\n\t\t{ channel, externalId, syncedAt }: OrderUpdateSyncInfoAction,\n\t) {\n\t\tif (!channel) return;\n\t\tconst resolvedType = this._storage.getByResourceIdentifier(\n\t\t\tcontext.projectKey,\n\t\t\tchannel,\n\t\t);\n\t\tif (!resolvedType) {\n\t\t\tthrow new Error(`Channel ${channel} not found`);\n\t\t}\n\n\t\tconst syncData: SyncInfo = {\n\t\t\tchannel: {\n\t\t\t\ttypeId: \"channel\",\n\t\t\t\tid: resolvedType.id,\n\t\t\t},\n\t\t\texternalId,\n\t\t\tsyncedAt: syncedAt ?? new Date().toISOString(),\n\t\t};\n\n\t\tif (!resource.syncInfo?.length) {\n\t\t\tresource.syncInfo = [syncData];\n\t\t} else {\n\t\t\tconst lastSyncInfo = resource.syncInfo[resource.syncInfo.length - 1];\n\t\t\tif (\n\t\t\t\tlastSyncInfo.channel.id !== syncData.channel.id ||\n\t\t\t\tlastSyncInfo.externalId !== syncData.externalId\n\t\t\t) {\n\t\t\t\tresource.syncInfo.push(syncData);\n\t\t\t}\n\t\t}\n\t}\n}\n","import assert from \"node:assert\";\nimport type {\n\tCart,\n\tCartReference,\n\tCustomLineItem,\n\tCustomLineItemImportDraft,\n\tGeneralError,\n\tLineItem,\n\tLineItemImportDraft,\n\tOrder,\n\tOrderFromCartDraft,\n\tOrderImportDraft,\n\tProduct,\n\tProductPagedQueryResponse,\n\tProductVariant,\n\tShippingInfo,\n\tShippingMethodDoesNotMatchCartError,\n\tShippingMethodReference,\n} from \"@commercetools/platform-sdk\";\nimport type { Config } from \"#src/config.ts\";\nimport { CommercetoolsError } from \"#src/exceptions.ts\";\nimport {\n\tgenerateRandomString,\n\tgetBaseResourceProperties,\n} from \"#src/helpers.ts\";\nimport {\n\tcalculateTaxedPriceFromRate,\n\tcalculateTaxTotals,\n} from \"#src/lib/tax.ts\";\nimport {\n\tcreateShippingInfoFromMethod,\n\tgetShippingMethodsMatchingCart,\n} from \"#src/shipping.ts\";\nimport type { Writable } from \"#src/types.ts\";\nimport type { RepositoryContext } from \"../abstract.ts\";\nimport { AbstractResourceRepository, type QueryParams } from \"../abstract.ts\";\nimport {\n\tcreateAddress,\n\tcreateCentPrecisionMoney,\n\tcreateCustomFields,\n\tcreatePrice,\n\tcreateTypedMoney,\n\tresolveStoreReference,\n} from \"../helpers.ts\";\nimport { OrderUpdateHandler } from \"./actions.ts\";\n\nexport class OrderRepository extends AbstractResourceRepository<\"order\"> {\n\tconstructor(config: Config) {\n\t\tsuper(\"order\", config);\n\t\tthis.actions = new OrderUpdateHandler(config.storage);\n\t}\n\n\tcreate(context: RepositoryContext, draft: OrderFromCartDraft): Order {\n\t\tassert(draft.cart, \"draft.cart is missing\");\n\t\treturn this.createFromCart(\n\t\t\tcontext,\n\t\t\t{\n\t\t\t\tid: draft.cart.id!,\n\t\t\t\ttypeId: \"cart\",\n\t\t\t},\n\t\t\tdraft.orderNumber,\n\t\t);\n\t}\n\n\tcreateFromCart(\n\t\tcontext: RepositoryContext,\n\t\tcartReference: CartReference,\n\t\torderNumber?: string,\n\t) {\n\t\tconst cart = this._storage.getByResourceIdentifier(\n\t\t\tcontext.projectKey,\n\t\t\tcartReference,\n\t\t) as Cart | null;\n\t\tif (!cart) {\n\t\t\tthrow new Error(\"Cannot find cart\");\n\t\t}\n\n\t\tconst resource: Writable<Order> = {\n\t\t\t...getBaseResourceProperties(),\n\t\t\tanonymousId: cart.anonymousId,\n\t\t\tbillingAddress: cart.billingAddress,\n\t\t\tcart: cartReference,\n\t\t\tcountry: cart.country,\n\t\t\tcustom: cart.custom,\n\t\t\tcustomerEmail: cart.customerEmail,\n\t\t\tcustomerGroup: cart.customerGroup,\n\t\t\tcustomerId: cart.customerId,\n\t\t\tcustomLineItems: [],\n\t\t\tdirectDiscounts: cart.directDiscounts,\n\t\t\tdiscountCodes: cart.discountCodes,\n\t\t\tdiscountOnTotalPrice: cart.discountOnTotalPrice,\n\t\t\tlastMessageSequenceNumber: 0,\n\t\t\tlineItems: cart.lineItems,\n\t\t\tlocale: cart.locale,\n\t\t\torderNumber: orderNumber ?? generateRandomString(10),\n\t\t\torderState: \"Open\",\n\t\t\torigin: \"Customer\",\n\t\t\tpaymentInfo: cart.paymentInfo,\n\t\t\trefusedGifts: [],\n\t\t\tshipping: cart.shipping,\n\t\t\tshippingAddress: cart.shippingAddress,\n\t\t\tshippingInfo: cart.shippingInfo,\n\t\t\tshippingMode: cart.shippingMode,\n\t\t\tsyncInfo: [],\n\t\t\ttaxCalculationMode: cart.taxCalculationMode,\n\t\t\ttaxedPrice: cart.taxedPrice,\n\t\t\ttaxedShippingPrice: cart.taxedShippingPrice,\n\t\t\ttaxMode: cart.taxMode,\n\t\t\ttaxRoundingMode: cart.taxRoundingMode,\n\t\t\ttotalPrice: cart.totalPrice,\n\t\t\tstore: cart.store,\n\t\t};\n\n\t\tconst { taxedPrice, taxedShippingPrice } = calculateTaxTotals({\n\t\t\tlineItems: cart.lineItems,\n\t\t\tcustomLineItems: cart.customLineItems,\n\t\t\tshippingInfo: cart.shippingInfo,\n\t\t\ttotalPrice: cart.totalPrice,\n\t\t});\n\t\tresource.taxedPrice = resource.taxedPrice ?? taxedPrice;\n\t\tresource.taxedShippingPrice =\n\t\t\tresource.taxedShippingPrice ?? taxedShippingPrice;\n\t\treturn this.saveNew(context, resource);\n\t}\n\n\timport(context: RepositoryContext, draft: OrderImportDraft): Order {\n\t\t// TODO: Check if order with given orderNumber already exists\n\t\tassert(this, \"OrderRepository not valid\");\n\t\tconst resource: Writable<Order> = {\n\t\t\t...getBaseResourceProperties(),\n\n\t\t\tbillingAddress: createAddress(\n\t\t\t\tdraft.billingAddress,\n\t\t\t\tcontext.projectKey,\n\t\t\t\tthis._storage,\n\t\t\t),\n\t\t\tshippingAddress: createAddress(\n\t\t\t\tdraft.shippingAddress,\n\t\t\t\tcontext.projectKey,\n\t\t\t\tthis._storage,\n\t\t\t),\n\n\t\t\tcustom: createCustomFields(\n\t\t\t\tdraft.custom,\n\t\t\t\tcontext.projectKey,\n\t\t\t\tthis._storage,\n\t\t\t),\n\t\t\tcustomerEmail: draft.customerEmail,\n\t\t\tcustomerId: draft.customerId,\n\t\t\tbusinessUnit: draft.businessUnit?.key\n\t\t\t\t? { typeId: \"business-unit\", key: draft.businessUnit.key }\n\t\t\t\t: undefined,\n\t\t\tlastMessageSequenceNumber: 0,\n\t\t\torderNumber: draft.orderNumber,\n\t\t\torderState: draft.orderState || \"Open\",\n\t\t\torigin: draft.origin || \"Customer\",\n\t\t\tpaymentState: draft.paymentState,\n\t\t\trefusedGifts: [],\n\t\t\tshippingMode: \"Single\",\n\t\t\tshipping: [],\n\t\t\tshippingInfo: undefined,\n\t\t\tstore: resolveStoreReference(\n\t\t\t\tdraft.store,\n\t\t\t\tcontext.projectKey,\n\t\t\t\tthis._storage,\n\t\t\t),\n\t\t\tsyncInfo: [],\n\n\t\t\tlineItems:\n\t\t\t\tdraft.lineItems?.map((item) =>\n\t\t\t\t\tthis.lineItemFromImportDraft.bind(this)(context, item),\n\t\t\t\t) || [],\n\t\t\tcustomLineItems:\n\t\t\t\tdraft.customLineItems?.map((item) =>\n\t\t\t\t\tthis.customLineItemFromImportDraft.bind(this)(context, item),\n\t\t\t\t) || [],\n\n\t\t\ttotalPrice: createCentPrecisionMoney(draft.totalPrice),\n\t\t};\n\n\t\t// Set shipping info after resource is created\n\t\tif (draft.shippingInfo?.shippingMethod) {\n\t\t\tconst { ...shippingMethodRef } = draft.shippingInfo.shippingMethod;\n\n\t\t\t// get id when reference is by key only\n\t\t\tif (shippingMethodRef.key && !shippingMethodRef.id) {\n\t\t\t\tconst shippingMethod =\n\t\t\t\t\tthis._storage.getByResourceIdentifier<\"shipping-method\">(\n\t\t\t\t\t\tcontext.projectKey,\n\t\t\t\t\t\tshippingMethodRef,\n\t\t\t\t\t);\n\t\t\t\tif (!shippingMethod) {\n\t\t\t\t\tthrow new CommercetoolsError<GeneralError>({\n\t\t\t\t\t\tcode: \"General\",\n\t\t\t\t\t\tmessage: `A shipping method with key '${shippingMethodRef.key}' does not exist.`,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tshippingMethodRef.id = shippingMethod.id;\n\t\t\t}\n\n\t\t\tresource.shippingInfo = this.createShippingInfo(context, resource, {\n\t\t\t\ttypeId: \"shipping-method\",\n\t\t\t\tid: shippingMethodRef.id as string,\n\t\t\t});\n\t\t}\n\n\t\tconst { taxedPrice, taxedShippingPrice } = calculateTaxTotals({\n\t\t\tlineItems: resource.lineItems,\n\t\t\tcustomLineItems: resource.customLineItems,\n\t\t\tshippingInfo: resource.shippingInfo,\n\t\t\ttotalPrice: resource.totalPrice,\n\t\t});\n\t\tresource.taxedPrice = resource.taxedPrice ?? taxedPrice;\n\t\tresource.taxedShippingPrice =\n\t\t\tresource.taxedShippingPrice ?? taxedShippingPrice;\n\n\t\treturn this.saveNew(context, resource);\n\t}\n\n\tprivate lineItemFromImportDraft(\n\t\tcontext: RepositoryContext,\n\t\tdraft: LineItemImportDraft,\n\t): LineItem {\n\t\tlet product: Product;\n\t\tlet variant: ProductVariant | undefined;\n\n\t\tif (draft.variant.sku) {\n\t\t\tvariant = {\n\t\t\t\tid: 0,\n\t\t\t\tsku: draft.variant.sku,\n\t\t\t};\n\n\t\t\tconst items = this._storage.query(context.projectKey, \"product\", {\n\t\t\t\twhere: [\n\t\t\t\t\t`masterData(current(masterVariant(sku=\"${draft.variant.sku}\"))) or masterData(current(variants(sku=\"${draft.variant.sku}\")))`,\n\t\t\t\t],\n\t\t\t}) as ProductPagedQueryResponse;\n\n\t\t\tif (items.count !== 1) {\n\t\t\t\tthrow new CommercetoolsError<GeneralError>({\n\t\t\t\t\tcode: \"General\",\n\t\t\t\t\tmessage: `A product containing a variant with SKU '${draft.variant.sku}' not found.`,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tproduct = items.results[0];\n\t\t\tif (product.masterData.current.masterVariant.sku === draft.variant.sku) {\n\t\t\t\tvariant = product.masterData.current.masterVariant;\n\t\t\t} else {\n\t\t\t\tvariant = product.masterData.current.variants.find(\n\t\t\t\t\t(v) => v.sku === draft.variant.sku,\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (!variant) {\n\t\t\t\tthrow new Error(\"Internal state error\");\n\t\t\t}\n\t\t} else {\n\t\t\tthrow new Error(\"No product found\");\n\t\t}\n\n\t\tconst quantity = draft.quantity ?? 1;\n\t\tconst totalPrice = createCentPrecisionMoney({\n\t\t\t...draft.price.value,\n\t\t\tcentAmount: (draft.price.value.centAmount ?? 0) * quantity,\n\t\t});\n\n\t\tconst lineItem: LineItem = {\n\t\t\t...getBaseResourceProperties(),\n\t\t\tcustom: createCustomFields(\n\t\t\t\tdraft.custom,\n\t\t\t\tcontext.projectKey,\n\t\t\t\tthis._storage,\n\t\t\t),\n\t\t\tdiscountedPricePerQuantity: [],\n\t\t\tlineItemMode: \"Standard\",\n\t\t\tname: draft.name,\n\t\t\tprice: createPrice(draft.price),\n\t\t\tpriceMode: \"Platform\",\n\t\t\tproductId: product.id,\n\t\t\tproductType: product.productType,\n\t\t\tquantity,\n\t\t\tstate: draft.state || [],\n\t\t\ttaxRate: draft.taxRate,\n\t\t\ttaxedPrice: calculateTaxedPriceFromRate(\n\t\t\t\ttotalPrice.centAmount,\n\t\t\t\ttotalPrice.currencyCode,\n\t\t\t\tdraft.taxRate,\n\t\t\t),\n\t\t\ttaxedPricePortions: [],\n\t\t\tperMethodTaxRate: [],\n\t\t\ttotalPrice,\n\t\t\tvariant: {\n\t\t\t\tid: variant.id,\n\t\t\t\tsku: variant.sku,\n\t\t\t\tprice: createPrice(draft.price),\n\t\t\t\tattributes: variant.attributes,\n\t\t\t},\n\t\t};\n\n\t\treturn lineItem;\n\t}\n\n\tprivate customLineItemFromImportDraft(\n\t\tcontext: RepositoryContext,\n\t\tdraft: CustomLineItemImportDraft,\n\t): CustomLineItem {\n\t\tconst quantity = draft.quantity ?? 1;\n\t\tconst totalPrice = createCentPrecisionMoney({\n\t\t\t...draft.money,\n\t\t\tcentAmount: (draft.money.centAmount ?? 0) * quantity,\n\t\t});\n\n\t\tconst lineItem: CustomLineItem = {\n\t\t\t...getBaseResourceProperties(),\n\t\t\tcustom: createCustomFields(\n\t\t\t\tdraft.custom,\n\t\t\t\tcontext.projectKey,\n\t\t\t\tthis._storage,\n\t\t\t),\n\t\t\tdiscountedPricePerQuantity: [],\n\t\t\tmoney: createTypedMoney(draft.money),\n\t\t\tname: draft.name,\n\t\t\tquantity,\n\t\t\tperMethodTaxRate: [],\n\t\t\tpriceMode: draft.priceMode ?? \"Standard\",\n\t\t\tslug: draft.slug,\n\t\t\tstate: [],\n\t\t\ttotalPrice,\n\t\t\ttaxedPrice: calculateTaxedPriceFromRate(\n\t\t\t\ttotalPrice.centAmount,\n\t\t\t\ttotalPrice.currencyCode,\n\t\t\t\tdraft.taxRate,\n\t\t\t),\n\t\t\ttaxedPricePortions: [],\n\t\t};\n\n\t\treturn lineItem;\n\t}\n\n\tgetWithOrderNumber(\n\t\tcontext: RepositoryContext,\n\t\torderNumber: string,\n\t\tparams: QueryParams = {},\n\t): Order | undefined {\n\t\tconst result = this._storage.query(context.projectKey, this.getTypeId(), {\n\t\t\t...params,\n\t\t\twhere: [`orderNumber=\"${orderNumber}\"`],\n\t\t});\n\t\tif (result.count === 1) {\n\t\t\treturn result.results[0] as Order;\n\t\t}\n\n\t\t// Catch this for now, should be checked when creating/updating\n\t\tif (result.count > 1) {\n\t\t\tthrow new Error(\"Duplicate order numbers\");\n\t\t}\n\n\t\treturn;\n\t}\n\n\tcreateShippingInfo(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Order>,\n\t\tshippingMethodRef: ShippingMethodReference,\n\t): ShippingInfo {\n\t\tconst cartLikeForMatching: Writable<Cart> = {\n\t\t\t...resource,\n\t\t\tcartState: \"Active\" as const,\n\t\t\tinventoryMode: \"None\" as const,\n\t\t\titemShippingAddresses: [],\n\t\t\tpriceRoundingMode: resource.taxRoundingMode || \"HalfEven\",\n\t\t\ttaxMode: resource.taxMode || \"Platform\",\n\t\t\ttaxCalculationMode: resource.taxCalculationMode || \"LineItemLevel\",\n\t\t\ttaxRoundingMode: resource.taxRoundingMode || \"HalfEven\",\n\t\t\tdiscountCodes: resource.discountCodes || [],\n\t\t\tdirectDiscounts: resource.directDiscounts || [],\n\t\t\tshippingInfo: undefined,\n\t\t};\n\n\t\tconst shippingMethods = getShippingMethodsMatchingCart(\n\t\t\tcontext,\n\t\t\tthis._storage,\n\t\t\tcartLikeForMatching,\n\t\t\t{\n\t\t\t\texpand: [\"zoneRates[*].zone\"],\n\t\t\t},\n\t\t);\n\n\t\tconst method = shippingMethods.results.find(\n\t\t\t(candidate) => candidate.id === shippingMethodRef.id,\n\t\t);\n\n\t\tif (!method) {\n\t\t\tthrow new CommercetoolsError<ShippingMethodDoesNotMatchCartError>({\n\t\t\t\tcode: \"ShippingMethodDoesNotMatchCart\",\n\t\t\t\tmessage: `The shipping method with ID '${shippingMethodRef.id}' is not allowed for the order with ID '${resource.id}'.`,\n\t\t\t});\n\t\t}\n\n\t\tconst baseShippingInfo = createShippingInfoFromMethod(\n\t\t\tcontext,\n\t\t\tthis._storage,\n\t\t\tresource,\n\t\t\tmethod,\n\t\t);\n\n\t\treturn {\n\t\t\t...baseShippingInfo,\n\t\t\tdeliveries: [],\n\t\t};\n\t}\n}\n","import type {\n\tInvalidJsonInputError,\n\tQuoteRequest,\n\tQuoteRequestSetCustomFieldAction,\n\tQuoteRequestSetCustomTypeAction,\n\tQuoteRequestTransitionStateAction,\n\tQuoteRequestUpdateAction,\n\tStateReference,\n} from \"@commercetools/platform-sdk\";\nimport { CommercetoolsError } from \"#src/exceptions.ts\";\nimport type { Writable } from \"#src/types.ts\";\nimport type { RepositoryContext, UpdateHandlerInterface } from \"../abstract.ts\";\nimport { AbstractUpdateHandler } from \"../abstract.ts\";\nimport { getReferenceFromResourceIdentifier } from \"../helpers.ts\";\n\nexport class QuoteRequestUpdateHandler\n\textends AbstractUpdateHandler\n\timplements\n\t\tPartial<UpdateHandlerInterface<QuoteRequest, QuoteRequestUpdateAction>>\n{\n\tsetCustomField(\n\t\tcontext: RepositoryContext,\n\t\tresource: QuoteRequest,\n\t\t{ name, value }: QuoteRequestSetCustomFieldAction,\n\t) {\n\t\tif (!resource.custom) {\n\t\t\tthrow new Error(\"Resource has no custom field\");\n\t\t}\n\t\tresource.custom.fields[name] = value;\n\t}\n\n\tsetCustomType(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<QuoteRequest>,\n\t\t{ type, fields }: QuoteRequestSetCustomTypeAction,\n\t) {\n\t\tif (!type) {\n\t\t\tresource.custom = undefined;\n\t\t} else {\n\t\t\tconst resolvedType = this._storage.getByResourceIdentifier(\n\t\t\t\tcontext.projectKey,\n\t\t\t\ttype,\n\t\t\t);\n\t\t\tif (!resolvedType) {\n\t\t\t\tthrow new Error(`Type ${type} not found`);\n\t\t\t}\n\n\t\t\tresource.custom = {\n\t\t\t\ttype: {\n\t\t\t\t\ttypeId: \"type\",\n\t\t\t\t\tid: resolvedType.id,\n\t\t\t\t},\n\t\t\t\tfields: fields || {},\n\t\t\t};\n\t\t}\n\t}\n\n\ttransitionState(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<QuoteRequest>,\n\t\t{ state, force }: QuoteRequestTransitionStateAction,\n\t) {\n\t\tlet stateReference: StateReference | undefined;\n\t\tif (state) {\n\t\t\tstateReference = getReferenceFromResourceIdentifier<StateReference>(\n\t\t\t\tstate,\n\t\t\t\tcontext.projectKey,\n\t\t\t\tthis._storage,\n\t\t\t);\n\t\t\tresource.state = stateReference;\n\t\t} else {\n\t\t\tthrow new CommercetoolsError<InvalidJsonInputError>(\n\t\t\t\t{\n\t\t\t\t\tcode: \"InvalidJsonInput\",\n\t\t\t\t\tmessage: \"Request body does not contain valid JSON.\",\n\t\t\t\t\tdetailedErrorMessage: \"actions -> state: Missing required value\",\n\t\t\t\t},\n\t\t\t\t400,\n\t\t\t);\n\t\t}\n\n\t\treturn resource;\n\t}\n}\n","import assert from \"node:assert\";\nimport type {\n\tCart,\n\tCartReference,\n\tMyQuoteRequestDraft,\n\tQuoteRequest,\n\tQuoteRequestDraft,\n} from \"@commercetools/platform-sdk\";\nimport type { Config } from \"#src/config.ts\";\nimport { getBaseResourceProperties } from \"#src/helpers.ts\";\nimport type { RepositoryContext } from \"../abstract.ts\";\nimport { AbstractResourceRepository } from \"../abstract.ts\";\nimport { QuoteRequestUpdateHandler } from \"./actions.ts\";\n\nexport class QuoteRequestRepository extends AbstractResourceRepository<\"quote-request\"> {\n\tconstructor(config: Config) {\n\t\tsuper(\"quote-request\", config);\n\t\tthis.actions = new QuoteRequestUpdateHandler(config.storage);\n\t}\n\n\tcreate(\n\t\tcontext: RepositoryContext,\n\t\tdraft: QuoteRequestDraft | MyQuoteRequestDraft,\n\t): QuoteRequest {\n\t\t// Handle the 'my' version of the draft\n\t\tif (\"cartId\" in draft) {\n\t\t\treturn this.createFromCart(context, {\n\t\t\t\tid: draft.cartId,\n\t\t\t\ttypeId: \"cart\",\n\t\t\t});\n\t\t}\n\n\t\tassert(draft.cart, \"draft.cart is missing\");\n\t\treturn this.createFromCart(context, {\n\t\t\tid: draft.cart.id!,\n\t\t\ttypeId: \"cart\",\n\t\t});\n\t}\n\n\tcreateFromCart(context: RepositoryContext, cartReference: CartReference) {\n\t\tconst cart = this._storage.getByResourceIdentifier(\n\t\t\tcontext.projectKey,\n\t\t\tcartReference,\n\t\t) as Cart | null;\n\t\tif (!cart) {\n\t\t\tthrow new Error(\"Cannot find cart\");\n\t\t}\n\n\t\tif (!cart.customerId) {\n\t\t\tthrow new Error(\"Cart does not have a customer\");\n\t\t}\n\n\t\tconst resource: QuoteRequest = {\n\t\t\t...getBaseResourceProperties(),\n\t\t\tbillingAddress: cart.billingAddress,\n\t\t\tcart: cartReference,\n\t\t\tcountry: cart.country,\n\t\t\tcustom: cart.custom,\n\t\t\tcustomer: {\n\t\t\t\ttypeId: \"customer\",\n\t\t\t\tid: cart.customerId,\n\t\t\t},\n\t\t\tcustomerGroup: cart.customerGroup,\n\t\t\tcustomLineItems: [],\n\t\t\tdirectDiscounts: cart.directDiscounts,\n\t\t\tlineItems: cart.lineItems,\n\t\t\tpaymentInfo: cart.paymentInfo,\n\t\t\tpriceRoundingMode: cart.priceRoundingMode,\n\t\t\tquoteRequestState: \"Submitted\",\n\t\t\tshippingAddress: cart.shippingAddress,\n\t\t\ttaxCalculationMode: cart.taxCalculationMode,\n\t\t\ttaxedPrice: cart.taxedPrice,\n\t\t\ttaxMode: cart.taxMode,\n\t\t\ttaxRoundingMode: cart.taxRoundingMode,\n\t\t\ttotalPrice: cart.totalPrice,\n\t\t\tstore: cart.store,\n\t\t};\n\t\treturn this.saveNew(context, resource);\n\t}\n}\n","import { CartRepository } from \"./cart/index.ts\";\nimport { OrderRepository } from \"./order/index.ts\";\nimport { QuoteRequestRepository } from \"./quote-request/index.ts\";\n\nexport class AsAssociateOrderRepository extends OrderRepository {}\nexport class AsAssociateCartRepository extends CartRepository {}\nexport class AsAssociateQuoteRequestRepository extends QuoteRequestRepository {}\n","import type {\n\tAssociateRole,\n\tAssociateRoleAddPermissionAction,\n\tAssociateRoleChangeBuyerAssignableAction,\n\tAssociateRoleDraft,\n\tAssociateRoleRemovePermissionAction,\n\tAssociateRoleSetCustomFieldAction,\n\tAssociateRoleSetCustomTypeAction,\n\tAssociateRoleSetNameAction,\n\tAssociateRoleSetPermissionsAction,\n\tAssociateRoleUpdateAction,\n} from \"@commercetools/platform-sdk\";\nimport type { Config } from \"#src/config.ts\";\nimport { getBaseResourceProperties } from \"../helpers.ts\";\nimport type { Writable } from \"../types.ts\";\nimport type { UpdateHandlerInterface } from \"./abstract.ts\";\nimport {\n\tAbstractResourceRepository,\n\tAbstractUpdateHandler,\n\ttype RepositoryContext,\n} from \"./abstract.ts\";\nimport { createCustomFields } from \"./helpers.ts\";\n\nexport class AssociateRoleRepository extends AbstractResourceRepository<\"associate-role\"> {\n\tconstructor(config: Config) {\n\t\tsuper(\"associate-role\", config);\n\t\tthis.actions = new AssociateRoleUpdateHandler(this._storage);\n\t}\n\n\tcreate(context: RepositoryContext, draft: AssociateRoleDraft): AssociateRole {\n\t\tconst resource: AssociateRole = {\n\t\t\t...getBaseResourceProperties(),\n\t\t\tkey: draft.key,\n\t\t\tname: draft.name,\n\t\t\tbuyerAssignable: draft.buyerAssignable || false,\n\t\t\tpermissions: draft.permissions || [],\n\t\t\tcustom: createCustomFields(\n\t\t\t\tdraft.custom,\n\t\t\t\tcontext.projectKey,\n\t\t\t\tthis._storage,\n\t\t\t),\n\t\t};\n\n\t\treturn this.saveNew(context, resource);\n\t}\n}\n\nclass AssociateRoleUpdateHandler\n\textends AbstractUpdateHandler\n\timplements\n\t\tPartial<UpdateHandlerInterface<AssociateRole, AssociateRoleUpdateAction>>\n{\n\taddPermission(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<AssociateRole>,\n\t\t{ permission }: AssociateRoleAddPermissionAction,\n\t) {\n\t\tif (!resource.permissions) {\n\t\t\tresource.permissions = [permission];\n\t\t} else {\n\t\t\tresource.permissions.push(permission);\n\t\t}\n\t}\n\n\tchangeBuyerAssignable(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<AssociateRole>,\n\t\t{ buyerAssignable }: AssociateRoleChangeBuyerAssignableAction,\n\t) {\n\t\tresource.buyerAssignable = buyerAssignable;\n\t}\n\n\tremovePermission(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<AssociateRole>,\n\t\t{ permission }: AssociateRoleRemovePermissionAction,\n\t) {\n\t\tif (!resource.permissions) {\n\t\t\treturn;\n\t\t}\n\n\t\tresource.permissions = resource.permissions.filter((p) => p !== permission);\n\t}\n\n\tsetBuyerAssignable(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<AssociateRole>,\n\t\t{ buyerAssignable }: AssociateRoleChangeBuyerAssignableAction,\n\t) {\n\t\tresource.buyerAssignable = buyerAssignable;\n\t}\n\n\tsetCustomFields(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<AssociateRole>,\n\t\t{ name, value }: AssociateRoleSetCustomFieldAction,\n\t) {\n\t\tif (!resource.custom) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (value === null) {\n\t\t\tdelete resource.custom.fields[name];\n\t\t} else {\n\t\t\tresource.custom.fields[name] = value;\n\t\t}\n\t}\n\n\tsetCustomType(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<AssociateRole>,\n\t\t{ type, fields }: AssociateRoleSetCustomTypeAction,\n\t) {\n\t\tif (type) {\n\t\t\tresource.custom = createCustomFields(\n\t\t\t\t{ type, fields },\n\t\t\t\tcontext.projectKey,\n\t\t\t\tthis._storage,\n\t\t\t);\n\t\t} else {\n\t\t\tresource.custom = undefined;\n\t\t}\n\t}\n\n\tsetName(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<AssociateRole>,\n\t\t{ name }: AssociateRoleSetNameAction,\n\t) {\n\t\tresource.name = name;\n\t}\n\n\tsetPermissions(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<AssociateRole>,\n\t\t{ permissions }: AssociateRoleSetPermissionsAction,\n\t) {\n\t\tresource.permissions = permissions || [];\n\t}\n}\n","import type {\n\tAttributeGroup,\n\tAttributeGroupChangeNameAction,\n\tAttributeGroupDraft,\n\tAttributeGroupSetAttributesAction,\n\tAttributeGroupSetDescriptionAction,\n\tAttributeGroupSetKeyAction,\n\tAttributeGroupUpdateAction,\n} from \"@commercetools/platform-sdk\";\nimport type { Config } from \"#src/config.ts\";\nimport { getBaseResourceProperties } from \"../helpers.ts\";\nimport type { Writable } from \"../types.ts\";\nimport type { UpdateHandlerInterface } from \"./abstract.ts\";\nimport {\n\tAbstractResourceRepository,\n\tAbstractUpdateHandler,\n\ttype RepositoryContext,\n} from \"./abstract.ts\";\n\nexport class AttributeGroupRepository extends AbstractResourceRepository<\"attribute-group\"> {\n\tconstructor(config: Config) {\n\t\tsuper(\"attribute-group\", config);\n\t\tthis.actions = new AttributeGroupUpdateHandler(this._storage);\n\t}\n\n\tcreate(\n\t\tcontext: RepositoryContext,\n\t\tdraft: AttributeGroupDraft,\n\t): AttributeGroup {\n\t\tconst resource: AttributeGroup = {\n\t\t\t...getBaseResourceProperties(),\n\t\t\tname: draft.name,\n\t\t\tdescription: draft.description,\n\t\t\tkey: draft.key,\n\t\t\tattributes: draft.attributes,\n\t\t};\n\t\treturn this.saveNew(context, resource);\n\t}\n}\n\nclass AttributeGroupUpdateHandler\n\textends AbstractUpdateHandler\n\timplements\n\t\tPartial<UpdateHandlerInterface<AttributeGroup, AttributeGroupUpdateAction>>\n{\n\tchangeName(\n\t\t_context: RepositoryContext,\n\t\tresource: Writable<AttributeGroup>,\n\t\t{ name }: AttributeGroupChangeNameAction,\n\t) {\n\t\tresource.name = name;\n\t}\n\n\tsetAttributes(\n\t\t_context: RepositoryContext,\n\t\tresource: Writable<AttributeGroup>,\n\t\t{ attributes }: AttributeGroupSetAttributesAction,\n\t) {\n\t\tresource.attributes = attributes;\n\t}\n\n\tsetDescription(\n\t\t_context: RepositoryContext,\n\t\tresource: Writable<AttributeGroup>,\n\t\t{ description }: AttributeGroupSetDescriptionAction,\n\t) {\n\t\tresource.description = description;\n\t}\n\n\tsetKey(\n\t\t_context: RepositoryContext,\n\t\tresource: Writable<AttributeGroup>,\n\t\t{ key }: AttributeGroupSetKeyAction,\n\t) {\n\t\tresource.key = key;\n\t}\n}\n","import type {\n\tAssociate,\n\tBusinessUnit,\n\tBusinessUnitAddAddressAction,\n\tBusinessUnitAddAssociateAction,\n\tBusinessUnitAddBillingAddressIdAction,\n\tBusinessUnitAddShippingAddressIdAction,\n\tBusinessUnitAddStoreAction,\n\tBusinessUnitChangeAddressAction,\n\tBusinessUnitChangeApprovalRuleModeAction,\n\tBusinessUnitChangeAssociateAction,\n\tBusinessUnitChangeAssociateModeAction,\n\tBusinessUnitChangeNameAction,\n\tBusinessUnitChangeParentUnitAction,\n\tBusinessUnitChangeStatusAction,\n\tBusinessUnitDraft,\n\tBusinessUnitRemoveAddressAction,\n\tBusinessUnitRemoveAssociateAction,\n\tBusinessUnitRemoveBillingAddressIdAction,\n\tBusinessUnitRemoveShippingAddressIdAction,\n\tBusinessUnitSetAddressCustomFieldAction,\n\tBusinessUnitSetAddressCustomTypeAction,\n\tBusinessUnitSetAssociatesAction,\n\tBusinessUnitSetContactEmailAction,\n\tBusinessUnitSetCustomFieldAction,\n\tBusinessUnitSetCustomTypeAction,\n\tBusinessUnitSetDefaultBillingAddressAction,\n\tBusinessUnitSetDefaultShippingAddressAction,\n\tBusinessUnitSetStoreModeAction,\n\tBusinessUnitUpdateAction,\n\tCompany,\n\tCompanyDraft,\n\tDivision,\n\tDivisionDraft,\n} from \"@commercetools/platform-sdk\";\nimport type { Config } from \"#src/config.ts\";\nimport { generateRandomString, getBaseResourceProperties } from \"../helpers.ts\";\nimport type { Writable } from \"../types.ts\";\nimport type { UpdateHandlerInterface } from \"./abstract.ts\";\nimport {\n\tAbstractResourceRepository,\n\tAbstractUpdateHandler,\n\ttype RepositoryContext,\n} from \"./abstract.ts\";\nimport {\n\tcreateAddress,\n\tcreateAssociate,\n\tcreateCustomFields,\n\tgetBusinessUnitKeyReference,\n\tgetStoreKeyReference,\n} from \"./helpers.ts\";\n\nexport class BusinessUnitRepository extends AbstractResourceRepository<\"business-unit\"> {\n\tconstructor(config: Config) {\n\t\tsuper(\"business-unit\", config);\n\t\tthis.actions = new BusinessUnitUpdateHandler(this._storage);\n\t}\n\n\tcreate(context: RepositoryContext, draft: BusinessUnitDraft): BusinessUnit {\n\t\tconst addresses =\n\t\t\tdraft.addresses?.map((address) => ({\n\t\t\t\t...address,\n\t\t\t\tid: generateRandomString(5),\n\t\t\t})) ?? [];\n\n\t\tconst defaultBillingAddressId =\n\t\t\taddresses.length > 0 && draft.defaultBillingAddress !== undefined\n\t\t\t\t? addresses[draft.defaultBillingAddress].id\n\t\t\t\t: undefined;\n\t\tconst defaultShippingAddressId =\n\t\t\taddresses.length > 0 && draft.defaultShippingAddress !== undefined\n\t\t\t\t? addresses[draft.defaultShippingAddress].id\n\t\t\t\t: undefined;\n\n\t\tconst shippingAddressIds = draft.shippingAddresses?.map(\n\t\t\t(i) => addresses[i].id,\n\t\t);\n\t\tconst billingAddressIds = draft.billingAddresses?.map(\n\t\t\t(i) => addresses[i].id,\n\t\t);\n\n\t\tconst resource = {\n\t\t\t...getBaseResourceProperties(),\n\t\t\tkey: draft.key,\n\t\t\tstatus: draft.status,\n\t\t\tstores: draft.stores?.map((s) =>\n\t\t\t\tgetStoreKeyReference(s, context.projectKey, this._storage),\n\t\t\t),\n\t\t\tstoreMode: draft.storeMode,\n\t\t\tname: draft.name,\n\t\t\tcontactEmail: draft.contactEmail,\n\t\t\taddresses: addresses,\n\t\t\tcustom: createCustomFields(\n\t\t\t\tdraft.custom,\n\t\t\t\tcontext.projectKey,\n\t\t\t\tthis._storage,\n\t\t\t),\n\t\t\tshippingAddressIds: shippingAddressIds,\n\t\t\tbillingAddressIds: billingAddressIds,\n\t\t\tdefaultShippingAddressId: defaultShippingAddressId,\n\t\t\tdefaultBillingAddressId: defaultBillingAddressId,\n\t\t\tassociateMode: draft.associateMode,\n\t\t\tapprovalRuleMode: draft.approvalRuleMode,\n\n\t\t\tassociates:\n\t\t\t\tdraft.associates?.map((a) =>\n\t\t\t\t\tcreateAssociate(a, context.projectKey, this._storage),\n\t\t\t\t) ?? [],\n\t\t};\n\n\t\tif (this._isDivisionDraft(draft)) {\n\t\t\tconst division = {\n\t\t\t\t...resource,\n\t\t\t\tunitType: \"Division\" as const,\n\t\t\t\tparentUnit: getBusinessUnitKeyReference(\n\t\t\t\t\tdraft.parentUnit,\n\t\t\t\t\tcontext.projectKey,\n\t\t\t\t\tthis._storage,\n\t\t\t\t),\n\t\t\t} as Division;\n\n\t\t\tthis.saveNew(context, division);\n\t\t\treturn division;\n\t\t}\n\t\tif (this._isCompanyDraft(draft)) {\n\t\t\tconst company = {\n\t\t\t\t...resource,\n\t\t\t\tunitType: \"Company\" as const,\n\t\t\t} as Company;\n\n\t\t\tthis.saveNew(context, company);\n\t\t\treturn company;\n\t\t}\n\n\t\tthrow new Error(\"Invalid business unit type\");\n\t}\n\n\tprivate _isCompanyDraft(draft: BusinessUnitDraft): draft is CompanyDraft {\n\t\treturn draft.unitType === \"Company\";\n\t}\n\n\tprivate _isDivisionDraft(draft: BusinessUnitDraft): draft is DivisionDraft {\n\t\treturn draft.unitType === \"Division\";\n\t}\n}\n\nclass BusinessUnitUpdateHandler\n\textends AbstractUpdateHandler\n\timplements\n\t\tPartial<UpdateHandlerInterface<BusinessUnit, BusinessUnitUpdateAction>>\n{\n\taddAddress(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<BusinessUnit>,\n\t\t{ address }: BusinessUnitAddAddressAction,\n\t) {\n\t\tconst newAddress = createAddress(\n\t\t\taddress,\n\t\t\tcontext.projectKey,\n\t\t\tthis._storage,\n\t\t);\n\t\tif (newAddress) {\n\t\t\tresource.addresses.push(newAddress);\n\t\t}\n\t}\n\n\taddAssociate(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<BusinessUnit>,\n\t\t{ associate }: BusinessUnitAddAssociateAction,\n\t) {\n\t\tconst newAssociate = createAssociate(\n\t\t\tassociate,\n\t\t\tcontext.projectKey,\n\t\t\tthis._storage,\n\t\t);\n\t\tif (newAssociate) {\n\t\t\tresource.associates.push(newAssociate);\n\t\t}\n\t}\n\n\taddStore(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<BusinessUnit>,\n\t\t{ store }: BusinessUnitAddStoreAction,\n\t) {\n\t\tconst newStore = getStoreKeyReference(\n\t\t\tstore,\n\t\t\tcontext.projectKey,\n\t\t\tthis._storage,\n\t\t);\n\t\tif (newStore) {\n\t\t\tif (!resource.stores) {\n\t\t\t\tresource.stores = [];\n\t\t\t}\n\n\t\t\tresource.stores.push(newStore);\n\t\t}\n\t}\n\n\tchangeAddress(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<BusinessUnit>,\n\t\t{ addressId, address }: BusinessUnitChangeAddressAction,\n\t) {\n\t\tconst existingAddressIndex = resource.addresses.findIndex(\n\t\t\t(addr) => addr.id === addressId,\n\t\t);\n\t\tif (existingAddressIndex === -1) {\n\t\t\tthrow new Error(`Address with id ${addressId} not found`);\n\t\t}\n\n\t\tconst newAddress = createAddress(\n\t\t\t{ ...address, id: addressId },\n\t\t\tcontext.projectKey,\n\t\t\tthis._storage,\n\t\t);\n\t\tif (newAddress) {\n\t\t\tresource.addresses[existingAddressIndex] = newAddress;\n\t\t}\n\t}\n\n\tchangeApprovalRuleMode(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<BusinessUnit>,\n\t\t{ approvalRuleMode }: BusinessUnitChangeApprovalRuleModeAction,\n\t) {\n\t\tresource.approvalRuleMode = approvalRuleMode;\n\t}\n\n\tchangeAssociateMode(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<BusinessUnit>,\n\t\t{ associateMode }: BusinessUnitChangeAssociateModeAction,\n\t) {\n\t\tresource.associateMode = associateMode;\n\t}\n\n\tchangeName(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<BusinessUnit>,\n\t\t{ name }: BusinessUnitChangeNameAction,\n\t) {\n\t\tresource.name = name;\n\t}\n\n\tchangeParentUnit(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<BusinessUnit>,\n\t\t{ parentUnit }: BusinessUnitChangeParentUnitAction,\n\t) {\n\t\tresource.parentUnit = getBusinessUnitKeyReference(\n\t\t\tparentUnit,\n\t\t\tcontext.projectKey,\n\t\t\tthis._storage,\n\t\t);\n\t}\n\n\tchangeStatus(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<BusinessUnit>,\n\t\t{ status }: BusinessUnitChangeStatusAction,\n\t) {\n\t\tresource.status = status;\n\t}\n\n\tsetAssociates(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<BusinessUnit>,\n\t\t{ associates }: BusinessUnitSetAssociatesAction,\n\t) {\n\t\tconst newAssociates = associates\n\t\t\t.map((a) => createAssociate(a, context.projectKey, this._storage))\n\t\t\t.filter((a): a is Writable<Associate> => a !== undefined);\n\t\tresource.associates = newAssociates || undefined;\n\t}\n\n\tremoveAssociate(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<BusinessUnit>,\n\t\t{ customer }: BusinessUnitRemoveAssociateAction,\n\t) {\n\t\tresource.associates = resource.associates.filter(\n\t\t\t(associate) => associate.customer.id !== customer.id,\n\t\t);\n\t}\n\n\tchangeAssociate(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<BusinessUnit>,\n\t\t{ associate }: BusinessUnitChangeAssociateAction,\n\t) {\n\t\tconst existingAssociateIndex = resource.associates.findIndex(\n\t\t\t(a) => a.customer.id === associate.customer.id,\n\t\t);\n\t\tif (existingAssociateIndex === -1) {\n\t\t\tthrow new Error(\n\t\t\t\t`Associate with customer id ${associate.customer.id} not found`,\n\t\t\t);\n\t\t}\n\n\t\tconst newAssociate = createAssociate(\n\t\t\tassociate,\n\t\t\tcontext.projectKey,\n\t\t\tthis._storage,\n\t\t);\n\t\tif (newAssociate) {\n\t\t\tresource.associates[existingAssociateIndex] = newAssociate;\n\t\t}\n\t}\n\n\tsetContactEmail(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<BusinessUnit>,\n\t\t{ contactEmail }: BusinessUnitSetContactEmailAction,\n\t) {\n\t\tresource.contactEmail = contactEmail;\n\t}\n\n\tsetCustomType(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<BusinessUnit>,\n\t\t{ type, fields }: BusinessUnitSetCustomTypeAction,\n\t) {\n\t\tif (type) {\n\t\t\tresource.custom = createCustomFields(\n\t\t\t\t{ type, fields },\n\t\t\t\tcontext.projectKey,\n\t\t\t\tthis._storage,\n\t\t\t);\n\t\t} else {\n\t\t\tresource.custom = undefined;\n\t\t}\n\t}\n\n\tsetStoreMode(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<BusinessUnit>,\n\t\t{ storeMode }: BusinessUnitSetStoreModeAction,\n\t) {\n\t\tresource.storeMode = storeMode;\n\t}\n\n\tsetDefaultShippingAddress(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<BusinessUnit>,\n\t\t{ addressId }: BusinessUnitSetDefaultShippingAddressAction,\n\t) {\n\t\tresource.defaultShippingAddressId = addressId;\n\t}\n\n\taddShippingAddressId(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<BusinessUnit>,\n\t\t{ addressId }: BusinessUnitAddShippingAddressIdAction,\n\t) {\n\t\tif (!resource.shippingAddressIds) {\n\t\t\tresource.shippingAddressIds = [];\n\t\t}\n\t\tif (addressId) {\n\t\t\tresource.shippingAddressIds.push(addressId);\n\t\t}\n\t}\n\n\tremoveShippingAddressId(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<BusinessUnit>,\n\t\t{ addressId }: BusinessUnitRemoveShippingAddressIdAction,\n\t) {\n\t\tif (resource.shippingAddressIds) {\n\t\t\tresource.shippingAddressIds = resource.shippingAddressIds.filter(\n\t\t\t\t(id) => id !== addressId,\n\t\t\t);\n\t\t}\n\t\tif (resource.defaultShippingAddressId === addressId) {\n\t\t\tresource.defaultShippingAddressId = undefined;\n\t\t}\n\t}\n\n\taddBillingAddressId(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<BusinessUnit>,\n\t\t{ addressId }: BusinessUnitAddBillingAddressIdAction,\n\t) {\n\t\tif (!resource.billingAddressIds) {\n\t\t\tresource.billingAddressIds = [];\n\t\t}\n\t\tif (addressId) {\n\t\t\tresource.billingAddressIds.push(addressId);\n\t\t}\n\t}\n\n\tremoveBillingAddressId(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<BusinessUnit>,\n\t\t{ addressId }: BusinessUnitRemoveBillingAddressIdAction,\n\t) {\n\t\tif (resource.billingAddressIds) {\n\t\t\tresource.billingAddressIds = resource.billingAddressIds.filter(\n\t\t\t\t(id) => id !== addressId,\n\t\t\t);\n\t\t}\n\t\tif (resource.defaultBillingAddressId === addressId) {\n\t\t\tresource.defaultBillingAddressId = undefined;\n\t\t}\n\t}\n\n\tsetDefaultBillingAddress(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<BusinessUnit>,\n\t\t{ addressId }: BusinessUnitSetDefaultBillingAddressAction,\n\t) {\n\t\tresource.defaultBillingAddressId = addressId;\n\t}\n\n\tsetCustomField(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<BusinessUnit>,\n\t\t{ name, value }: BusinessUnitSetCustomFieldAction,\n\t) {\n\t\tif (!resource.custom) {\n\t\t\tthrow new Error(\"Resource has no custom type\");\n\t\t}\n\t\tresource.custom.fields[name] = value;\n\t}\n\n\tsetAddressCustomField(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<BusinessUnit>,\n\t\t{ addressId, name, value }: BusinessUnitSetAddressCustomFieldAction,\n\t) {\n\t\tconst address = resource.addresses.find((addr) => addr.id === addressId);\n\t\tif (!address) {\n\t\t\tthrow new Error(`Address with id ${addressId} not found`);\n\t\t}\n\t\tif (!address.custom) {\n\t\t\t// If the address doesn't have custom fields, we need to initialize them\n\t\t\t// This might require a type to be set first, but we'll just create minimal structure\n\t\t\tthrow new Error(\n\t\t\t\t\"Address has no custom type set. Use setAddressCustomType first.\",\n\t\t\t);\n\t\t}\n\t\taddress.custom.fields[name] = value;\n\t}\n\n\tsetAddressCustomType(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<BusinessUnit>,\n\t\t{ addressId, type, fields }: BusinessUnitSetAddressCustomTypeAction,\n\t) {\n\t\tconst address = resource.addresses.find((addr) => addr.id === addressId);\n\t\tif (!address) {\n\t\t\tthrow new Error(`Address with id ${addressId} not found`);\n\t\t}\n\n\t\tif (!type) {\n\t\t\taddress.custom = undefined;\n\t\t} else {\n\t\t\taddress.custom = createCustomFields(\n\t\t\t\t{ type, fields },\n\t\t\t\tcontext.projectKey,\n\t\t\t\tthis._storage,\n\t\t\t);\n\t\t}\n\t}\n\n\tremoveAddress(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<BusinessUnit>,\n\t\t{ addressId }: BusinessUnitRemoveAddressAction,\n\t) {\n\t\tresource.addresses = resource.addresses.filter(\n\t\t\t(addr) => addr.id !== addressId,\n\t\t);\n\n\t\tif (resource.shippingAddressIds) {\n\t\t\tresource.shippingAddressIds = resource.shippingAddressIds.filter(\n\t\t\t\t(id) => id !== addressId,\n\t\t\t);\n\t\t}\n\t\tif (resource.billingAddressIds) {\n\t\t\tresource.billingAddressIds = resource.billingAddressIds.filter(\n\t\t\t\t(id) => id !== addressId,\n\t\t\t);\n\t\t}\n\n\t\tif (resource.defaultShippingAddressId === addressId) {\n\t\t\tresource.defaultShippingAddressId = undefined;\n\t\t}\n\t\tif (resource.defaultBillingAddressId === addressId) {\n\t\t\tresource.defaultBillingAddressId = undefined;\n\t\t}\n\t}\n}\n","import type {\n\tCartDiscount,\n\tCartDiscountChangeIsActiveAction,\n\tCartDiscountChangeSortOrderAction,\n\tCartDiscountChangeTargetAction,\n\tCartDiscountSetCustomFieldAction,\n\tCartDiscountSetCustomTypeAction,\n\tCartDiscountSetDescriptionAction,\n\tCartDiscountSetKeyAction,\n\tCartDiscountSetStoresAction,\n\tCartDiscountSetValidFromAction,\n\tCartDiscountSetValidFromAndUntilAction,\n\tCartDiscountSetValidUntilAction,\n\tCartDiscountUpdateAction,\n\tInvalidOperationError,\n} from \"@commercetools/platform-sdk\";\nimport { CommercetoolsError } from \"#src/exceptions.ts\";\nimport { getStoreKeyReference } from \"#src/repositories/helpers.ts\";\nimport type { Writable } from \"#src/types.ts\";\nimport type { UpdateHandlerInterface } from \"../abstract.ts\";\nimport { AbstractUpdateHandler, type RepositoryContext } from \"../abstract.ts\";\n\nexport class CartDiscountUpdateHandler\n\textends AbstractUpdateHandler\n\timplements\n\t\tPartial<UpdateHandlerInterface<CartDiscount, CartDiscountUpdateAction>>\n{\n\tchangeIsActive(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<CartDiscount>,\n\t\t{ isActive }: CartDiscountChangeIsActiveAction,\n\t) {\n\t\tresource.isActive = isActive;\n\t}\n\n\tchangeSortOrder(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<CartDiscount>,\n\t\t{ sortOrder }: CartDiscountChangeSortOrderAction,\n\t) {\n\t\tresource.sortOrder = sortOrder;\n\t}\n\n\tchangeTarget(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<CartDiscount>,\n\t\t{ target }: CartDiscountChangeTargetAction,\n\t) {\n\t\tresource.target = target;\n\t}\n\n\tsetCustomField(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<CartDiscount>,\n\t\t{ name, value }: CartDiscountSetCustomFieldAction,\n\t) {\n\t\tif (!resource.custom) {\n\t\t\treturn;\n\t\t}\n\t\tif (value === null) {\n\t\t\tif (name in resource.custom.fields) {\n\t\t\t\tdelete resource.custom.fields[name];\n\t\t\t} else {\n\t\t\t\tthrow new CommercetoolsError<InvalidOperationError>(\n\t\t\t\t\t{\n\t\t\t\t\t\tcode: \"InvalidOperation\",\n\t\t\t\t\t\tmessage: `Cannot remove custom field ${name} because it does not exist.`,\n\t\t\t\t\t},\n\t\t\t\t\t400,\n\t\t\t\t);\n\t\t\t}\n\t\t} else {\n\t\t\tresource.custom.fields[name] = value;\n\t\t}\n\t}\n\n\tsetCustomType(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<CartDiscount>,\n\t\t{ type, fields }: CartDiscountSetCustomTypeAction,\n\t) {\n\t\tif (!type) {\n\t\t\tresource.custom = undefined;\n\t\t} else {\n\t\t\tconst resolvedType = this._storage.getByResourceIdentifier(\n\t\t\t\tcontext.projectKey,\n\t\t\t\ttype,\n\t\t\t);\n\t\t\tif (!resolvedType) {\n\t\t\t\tthrow new Error(`Type ${type} not found`);\n\t\t\t}\n\n\t\t\tresource.custom = {\n\t\t\t\ttype: {\n\t\t\t\t\ttypeId: \"type\",\n\t\t\t\t\tid: resolvedType.id,\n\t\t\t\t},\n\t\t\t\tfields: fields || {},\n\t\t\t};\n\t\t}\n\t}\n\n\tsetDescription(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<CartDiscount>,\n\t\t{ description }: CartDiscountSetDescriptionAction,\n\t) {\n\t\tresource.description = description;\n\t}\n\n\tsetKey(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<CartDiscount>,\n\t\t{ key }: CartDiscountSetKeyAction,\n\t) {\n\t\tresource.key = key;\n\t}\n\n\tsetStores(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<CartDiscount>,\n\t\t{ stores }: CartDiscountSetStoresAction,\n\t) {\n\t\tresource.stores = stores?.map((s) =>\n\t\t\tgetStoreKeyReference(s, context.projectKey, this._storage),\n\t\t);\n\t}\n\n\tsetValidFrom(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<CartDiscount>,\n\t\t{ validFrom }: CartDiscountSetValidFromAction,\n\t) {\n\t\tresource.validFrom = validFrom;\n\t}\n\n\tsetValidFromAndUntil(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<CartDiscount>,\n\t\t{ validFrom, validUntil }: CartDiscountSetValidFromAndUntilAction,\n\t) {\n\t\tresource.validFrom = validFrom;\n\t\tresource.validUntil = validUntil;\n\t}\n\n\tsetValidUntil(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<CartDiscount>,\n\t\t{ validUntil }: CartDiscountSetValidUntilAction,\n\t) {\n\t\tresource.validUntil = validUntil;\n\t}\n}\n","import type {\n\tCartDiscount,\n\tCartDiscountDraft,\n\tCartDiscountValueAbsolute,\n\tCartDiscountValueDraft,\n\tCartDiscountValueFixed,\n\tCartDiscountValueGiftLineItem,\n\tCartDiscountValueRelative,\n} from \"@commercetools/platform-sdk\";\nimport type { Config } from \"#src/config.ts\";\nimport { getBaseResourceProperties } from \"#src/helpers.ts\";\nimport {\n\tAbstractResourceRepository,\n\ttype RepositoryContext,\n} from \"../abstract.ts\";\nimport {\n\tcreateCustomFields,\n\tcreateTypedMoney,\n\tgetStoreKeyReference,\n} from \"../helpers.ts\";\nimport { CartDiscountUpdateHandler } from \"./actions.ts\";\n\nexport class CartDiscountRepository extends AbstractResourceRepository<\"cart-discount\"> {\n\tconstructor(config: Config) {\n\t\tsuper(\"cart-discount\", config);\n\t\tthis.actions = new CartDiscountUpdateHandler(config.storage);\n\t}\n\n\tcreate(context: RepositoryContext, draft: CartDiscountDraft): CartDiscount {\n\t\tconst resource: CartDiscount = {\n\t\t\t...getBaseResourceProperties(),\n\t\t\tkey: draft.key,\n\t\t\tdescription: draft.description,\n\t\t\tcartPredicate: draft.cartPredicate,\n\t\t\tisActive: draft.isActive || false,\n\t\t\tname: draft.name,\n\t\t\tstores:\n\t\t\t\tdraft.stores?.map((s) =>\n\t\t\t\t\tgetStoreKeyReference(s, context.projectKey, this._storage),\n\t\t\t\t) ?? [],\n\t\t\treferences: [],\n\t\t\ttarget: draft.target,\n\t\t\trequiresDiscountCode: draft.requiresDiscountCode || false,\n\t\t\tsortOrder: draft.sortOrder ?? \"0.1\",\n\t\t\tstackingMode: draft.stackingMode || \"Stacking\",\n\t\t\tvalidFrom: draft.validFrom,\n\t\t\tvalidUntil: draft.validUntil,\n\t\t\tvalue: this.transformValueDraft(draft.value),\n\t\t\tcustom: createCustomFields(\n\t\t\t\tdraft.custom,\n\t\t\t\tcontext.projectKey,\n\t\t\t\tthis._storage,\n\t\t\t),\n\t\t};\n\t\treturn this.saveNew(context, resource);\n\t}\n\n\tprivate transformValueDraft(value: CartDiscountValueDraft) {\n\t\tswitch (value.type) {\n\t\t\tcase \"absolute\": {\n\t\t\t\treturn {\n\t\t\t\t\ttype: \"absolute\",\n\t\t\t\t\tmoney: value.money.map(createTypedMoney),\n\t\t\t\t} as CartDiscountValueAbsolute;\n\t\t\t}\n\t\t\tcase \"fixed\": {\n\t\t\t\treturn {\n\t\t\t\t\ttype: \"fixed\",\n\t\t\t\t\tmoney: value.money.map(createTypedMoney),\n\t\t\t\t} as CartDiscountValueFixed;\n\t\t\t}\n\t\t\tcase \"giftLineItem\": {\n\t\t\t\treturn {\n\t\t\t\t\t...value,\n\t\t\t\t} as CartDiscountValueGiftLineItem;\n\t\t\t}\n\t\t\tcase \"relative\": {\n\t\t\t\treturn {\n\t\t\t\t\t...value,\n\t\t\t\t} as CartDiscountValueRelative;\n\t\t\t}\n\t\t}\n\t}\n}\n","/**\n * This module implements the reference expansion as imeplemented by\n * commercetools.\n *\n * See https://docs.commercetools.com/api/general-concepts#reference-expansion\n *\n * TODO: implement support for multi-dimensional array\n */\ntype ExpandResult = {\n\telement: string;\n\tindex?: string | number;\n\trest?: string;\n};\n\nexport const parseExpandClause = (clause: string): ExpandResult => {\n\tconst result: ExpandResult = {\n\t\telement: clause,\n\t\tindex: undefined,\n\t\trest: undefined,\n\t};\n\n\tconst pos = clause.indexOf(\".\");\n\tif (pos > 0) {\n\t\tresult.element = clause.substring(0, pos);\n\t\tresult.rest = clause.substring(pos + 1);\n\t}\n\n\tconst match = result.element.match(/\\[([^\\]+])]/);\n\tif (match) {\n\t\tresult.index = match[1] === \"*\" ? \"*\" : Number.parseInt(match[1], 10);\n\t\tresult.element = result.element.substring(0, match.index);\n\t}\n\treturn result;\n};\n","import type {\n\tAsset,\n\tAssetDraft,\n\tCategory,\n\tCategoryAddAssetAction,\n\tCategoryChangeAssetNameAction,\n\tCategoryChangeNameAction,\n\tCategoryChangeParentAction,\n\tCategoryChangeSlugAction,\n\tCategoryRemoveAssetAction,\n\tCategorySetAssetDescriptionAction,\n\tCategorySetAssetSourcesAction,\n\tCategorySetCustomFieldAction,\n\tCategorySetCustomTypeAction,\n\tCategorySetDescriptionAction,\n\tCategorySetKeyAction,\n\tCategorySetMetaDescriptionAction,\n\tCategorySetMetaKeywordsAction,\n\tCategorySetMetaTitleAction,\n\tCategoryUpdateAction,\n} from \"@commercetools/platform-sdk\";\nimport { v4 as uuidv4 } from \"uuid\";\nimport type { Writable } from \"#src/types.ts\";\nimport type { RepositoryContext, UpdateHandlerInterface } from \"../abstract.ts\";\nimport { AbstractUpdateHandler } from \"../abstract.ts\";\nimport { createCustomFields } from \"../helpers.ts\";\n\nexport class CategoryUpdateHandler\n\textends AbstractUpdateHandler\n\timplements Partial<UpdateHandlerInterface<Category, CategoryUpdateAction>>\n{\n\taddAsset(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Category>,\n\t\t{ asset }: CategoryAddAssetAction,\n\t) {\n\t\tif (!resource.assets) {\n\t\t\tresource.assets = [this.assetFromAssetDraft(asset, context)];\n\t\t} else {\n\t\t\tresource.assets.push(this.assetFromAssetDraft(asset, context));\n\t\t}\n\t}\n\n\tchangeAssetName(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Category>,\n\t\t{ assetId, assetKey, name }: CategoryChangeAssetNameAction,\n\t) {\n\t\tresource.assets?.forEach((asset) => {\n\t\t\tif (assetId && assetId === asset.id) {\n\t\t\t\tasset.name = name;\n\t\t\t}\n\t\t\tif (assetKey && assetKey === asset.key) {\n\t\t\t\tasset.name = name;\n\t\t\t}\n\t\t});\n\t}\n\n\tchangeName(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Category>,\n\t\t{ name }: CategoryChangeNameAction,\n\t) {\n\t\tresource.name = name;\n\t}\n\n\tchangeParent(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Category>,\n\t\t{ parent }: CategoryChangeParentAction,\n\t) {\n\t\tconst category = this._storage.getByResourceIdentifier(\n\t\t\tcontext.projectKey,\n\t\t\tparent,\n\t\t);\n\t\tif (!category) {\n\t\t\tthrow new Error(\"No category found for reference\");\n\t\t}\n\t\tresource.parent = {\n\t\t\ttypeId: \"category\",\n\t\t\tid: category.id,\n\t\t};\n\t}\n\n\tchangeSlug(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Category>,\n\t\t{ slug }: CategoryChangeSlugAction,\n\t) {\n\t\tresource.slug = slug;\n\t}\n\n\tremoveAsset(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Category>,\n\t\t{ assetId, assetKey }: CategoryRemoveAssetAction,\n\t) {\n\t\tif (!resource.assets) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (assetId) {\n\t\t\tresource.assets = resource.assets.filter((obj) => obj.id !== assetId);\n\n\t\t\treturn;\n\t\t}\n\n\t\tif (assetKey) {\n\t\t\tresource.assets = resource.assets.filter((obj) => obj.key !== assetKey);\n\n\t\t\treturn;\n\t\t}\n\t}\n\n\tsetAssetDescription(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Category>,\n\t\t{ assetId, assetKey, description }: CategorySetAssetDescriptionAction,\n\t) {\n\t\tresource.assets?.forEach((asset) => {\n\t\t\tif (assetId && assetId === asset.id) {\n\t\t\t\tasset.description = description;\n\t\t\t}\n\t\t\tif (assetKey && assetKey === asset.key) {\n\t\t\t\tasset.description = description;\n\t\t\t}\n\t\t});\n\t}\n\n\tsetAssetSources(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Category>,\n\t\t{ assetId, assetKey, sources }: CategorySetAssetSourcesAction,\n\t) {\n\t\tresource.assets?.forEach((asset) => {\n\t\t\tif (assetId && assetId === asset.id) {\n\t\t\t\tasset.sources = sources;\n\t\t\t}\n\t\t\tif (assetKey && assetKey === asset.key) {\n\t\t\t\tasset.sources = sources;\n\t\t\t}\n\t\t});\n\t}\n\n\tsetCustomField(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Category>,\n\t\t{ name, value }: CategorySetCustomFieldAction,\n\t) {\n\t\tif (!resource.custom) {\n\t\t\treturn;\n\t\t}\n\t\tif (value === null) {\n\t\t\tdelete resource.custom.fields[name];\n\t\t} else {\n\t\t\tresource.custom.fields[name] = value;\n\t\t}\n\t}\n\n\tsetCustomType(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Category>,\n\t\t{ type, fields }: CategorySetCustomTypeAction,\n\t) {\n\t\tif (type) {\n\t\t\tresource.custom = createCustomFields(\n\t\t\t\t{ type, fields },\n\t\t\t\tcontext.projectKey,\n\t\t\t\tthis._storage,\n\t\t\t);\n\t\t} else {\n\t\t\tresource.custom = undefined;\n\t\t}\n\t}\n\n\tsetDescription(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Category>,\n\t\t{ description }: CategorySetDescriptionAction,\n\t) {\n\t\tresource.description = description;\n\t}\n\n\tsetKey(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Category>,\n\t\t{ key }: CategorySetKeyAction,\n\t) {\n\t\tresource.key = key;\n\t}\n\n\tsetMetaDescription(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Category>,\n\t\t{ metaDescription }: CategorySetMetaDescriptionAction,\n\t) {\n\t\tresource.metaDescription = metaDescription;\n\t}\n\n\tsetMetaKeywords(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Category>,\n\t\t{ metaKeywords }: CategorySetMetaKeywordsAction,\n\t) {\n\t\tresource.metaKeywords = metaKeywords;\n\t}\n\n\tsetMetaTitle(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Category>,\n\t\t{ metaTitle }: CategorySetMetaTitleAction,\n\t) {\n\t\tresource.metaTitle = metaTitle;\n\t}\n\n\tassetFromAssetDraft = (\n\t\tdraft: AssetDraft,\n\t\tcontext: RepositoryContext,\n\t): Asset => ({\n\t\t...draft,\n\t\tid: uuidv4(),\n\t\tcustom: createCustomFields(draft.custom, context.projectKey, this._storage),\n\t});\n}\n","import type {\n\tCategory,\n\tCategoryDraft,\n\tCategoryReference,\n} from \"@commercetools/platform-sdk\";\nimport { v4 as uuidv4 } from \"uuid\";\nimport type { Config } from \"#src/config.ts\";\nimport { getBaseResourceProperties } from \"#src/helpers.ts\";\nimport { parseExpandClause } from \"#src/lib/expandParser.ts\";\nimport type { Writable } from \"#src/types.ts\";\nimport type { GetParams } from \"../abstract.ts\";\nimport {\n\tAbstractResourceRepository,\n\ttype RepositoryContext,\n} from \"../abstract.ts\";\nimport { createCustomFields } from \"../helpers.ts\";\nimport { CategoryUpdateHandler } from \"./actions.ts\";\n\nexport class CategoryRepository extends AbstractResourceRepository<\"category\"> {\n\tconstructor(config: Config) {\n\t\tsuper(\"category\", config);\n\t\tthis.actions = new CategoryUpdateHandler(this._storage);\n\t}\n\n\tcreate(context: RepositoryContext, draft: CategoryDraft): Category {\n\t\tconst resource: Category = {\n\t\t\t...getBaseResourceProperties(),\n\t\t\tkey: draft.key,\n\t\t\tname: draft.name,\n\t\t\tslug: draft.slug,\n\t\t\tdescription: draft.description,\n\t\t\tmetaDescription: draft.metaDescription,\n\t\t\tmetaKeywords: draft.metaKeywords,\n\t\t\torderHint: draft.orderHint || \"\",\n\t\t\texternalId: draft.externalId || \"\",\n\t\t\tparent: draft.parent\n\t\t\t\t? { typeId: \"category\", id: draft.parent.id! }\n\t\t\t\t: undefined,\n\t\t\tancestors: [], // Resolved at runtime\n\t\t\tassets:\n\t\t\t\tdraft.assets?.map((d) => ({\n\t\t\t\t\tid: uuidv4(),\n\t\t\t\t\tname: d.name,\n\t\t\t\t\tdescription: d.description,\n\t\t\t\t\tsources: d.sources,\n\t\t\t\t\ttags: d.tags,\n\t\t\t\t\tkey: d.key,\n\t\t\t\t\tcustom: createCustomFields(\n\t\t\t\t\t\tdraft.custom,\n\t\t\t\t\t\tcontext.projectKey,\n\t\t\t\t\t\tthis._storage,\n\t\t\t\t\t),\n\t\t\t\t})) || [],\n\t\t\tcustom: createCustomFields(\n\t\t\t\tdraft.custom,\n\t\t\t\tcontext.projectKey,\n\t\t\t\tthis._storage,\n\t\t\t),\n\t\t};\n\t\treturn this.saveNew(context, resource);\n\t}\n\n\tpostProcessResource(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Category>,\n\t\tparams?: GetParams,\n\t): Category {\n\t\tlet node: Category = resource;\n\t\tconst ancestors: CategoryReference[] = [];\n\n\t\t// TODO: The expand clause here is a hack, the current expand architecture\n\t\t// is not able to handle the case for 'dynamic' fields like ancestors which\n\t\t// are resolved at runtime. We should do the expand resolution post query\n\t\t// execution for all resources\n\n\t\tconst expandClauses = params?.expand?.map(parseExpandClause) ?? [];\n\t\tconst addExpand = expandClauses?.find(\n\t\t\t(c) => c.element === \"ancestors\" && c.index === \"*\",\n\t\t);\n\n\t\twhile (node.parent) {\n\t\t\tnode = this._storage.getByResourceIdentifier<\"category\">(\n\t\t\t\tcontext.projectKey,\n\t\t\t\tnode.parent,\n\t\t\t);\n\t\t\tancestors.push({\n\t\t\t\ttypeId: \"category\",\n\t\t\t\tid: node.id,\n\t\t\t\tobj: addExpand ? node : undefined,\n\t\t\t});\n\t\t}\n\n\t\tresource.ancestors = ancestors;\n\t\treturn resource;\n\t}\n}\n","import type {\n\tChannel,\n\tChannelChangeDescriptionAction,\n\tChannelChangeKeyAction,\n\tChannelChangeNameAction,\n\tChannelDraft,\n\tChannelSetAddressAction,\n\tChannelSetCustomFieldAction,\n\tChannelSetCustomTypeAction,\n\tChannelSetGeoLocationAction,\n\tChannelUpdateAction,\n} from \"@commercetools/platform-sdk\";\nimport type { Config } from \"#src/config.ts\";\nimport { getBaseResourceProperties } from \"../helpers.ts\";\nimport type { Writable } from \"../types.ts\";\nimport type { UpdateHandlerInterface } from \"./abstract.ts\";\nimport {\n\tAbstractResourceRepository,\n\tAbstractUpdateHandler,\n\ttype RepositoryContext,\n} from \"./abstract.ts\";\nimport { createAddress, createCustomFields } from \"./helpers.ts\";\n\nexport class ChannelRepository extends AbstractResourceRepository<\"channel\"> {\n\tconstructor(config: Config) {\n\t\tsuper(\"channel\", config);\n\t\tthis.actions = new ChannelUpdateHandler(this._storage);\n\t}\n\n\tcreate(context: RepositoryContext, draft: ChannelDraft): Channel {\n\t\tconst resource: Channel = {\n\t\t\t...getBaseResourceProperties(),\n\t\t\tkey: draft.key,\n\t\t\tname: draft.name,\n\t\t\tdescription: draft.description,\n\t\t\troles: draft.roles || [],\n\t\t\tgeoLocation: draft.geoLocation,\n\t\t\taddress: createAddress(draft.address, context.projectKey, this._storage),\n\t\t\tcustom: createCustomFields(\n\t\t\t\tdraft.custom,\n\t\t\t\tcontext.projectKey,\n\t\t\t\tthis._storage,\n\t\t\t),\n\t\t};\n\t\treturn this.saveNew(context, resource);\n\t}\n}\n\nclass ChannelUpdateHandler\n\textends AbstractUpdateHandler\n\timplements Partial<UpdateHandlerInterface<Channel, ChannelUpdateAction>>\n{\n\tchangeDescription(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Channel>,\n\t\t{ description }: ChannelChangeDescriptionAction,\n\t) {\n\t\tresource.description = description;\n\t}\n\n\tchangeKey(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Channel>,\n\t\t{ key }: ChannelChangeKeyAction,\n\t) {\n\t\tresource.key = key;\n\t}\n\n\tchangeName(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Channel>,\n\t\t{ name }: ChannelChangeNameAction,\n\t) {\n\t\tresource.name = name;\n\t}\n\n\tsetAddress(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Channel>,\n\t\t{ address }: ChannelSetAddressAction,\n\t) {\n\t\tresource.address = createAddress(\n\t\t\taddress,\n\t\t\tcontext.projectKey,\n\t\t\tthis._storage,\n\t\t);\n\t}\n\n\tsetCustomField(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Channel>,\n\t\t{ name, value }: ChannelSetCustomFieldAction,\n\t) {\n\t\tif (!resource.custom) {\n\t\t\treturn;\n\t\t}\n\t\tif (value === null) {\n\t\t\tdelete resource.custom.fields[name];\n\t\t} else {\n\t\t\tresource.custom.fields[name] = value;\n\t\t}\n\t}\n\n\tsetCustomType(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Channel>,\n\t\t{ type, fields }: ChannelSetCustomTypeAction,\n\t) {\n\t\tif (type) {\n\t\t\tresource.custom = createCustomFields(\n\t\t\t\t{ type, fields },\n\t\t\t\tcontext.projectKey,\n\t\t\t\tthis._storage,\n\t\t\t);\n\t\t} else {\n\t\t\tresource.custom = undefined;\n\t\t}\n\t}\n\n\tsetGeoLocation(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Channel>,\n\t\t{ geoLocation }: ChannelSetGeoLocationAction,\n\t) {\n\t\tresource.geoLocation = geoLocation;\n\t}\n}\n","import type {\n\tCustomObject,\n\tCustomObjectDraft,\n\tInvalidOperationError,\n} from \"@commercetools/platform-sdk\";\nimport type { Config } from \"#src/config.ts\";\nimport { CommercetoolsError } from \"#src/exceptions.ts\";\nimport { cloneObject, getBaseResourceProperties } from \"../helpers.ts\";\nimport type { Writable } from \"../types.ts\";\nimport type { QueryParams } from \"./abstract.ts\";\nimport {\n\tAbstractResourceRepository,\n\ttype RepositoryContext,\n} from \"./abstract.ts\";\nimport { checkConcurrentModification } from \"./errors.ts\";\n\nexport class CustomObjectRepository extends AbstractResourceRepository<\"key-value-document\"> {\n\tconstructor(config: Config) {\n\t\tsuper(\"key-value-document\", config);\n\t}\n\n\tcreate(\n\t\tcontext: RepositoryContext,\n\t\tdraft: Writable<CustomObjectDraft>,\n\t): CustomObject {\n\t\tconst current = this.getWithContainerAndKey(\n\t\t\tcontext,\n\t\t\tdraft.container,\n\t\t\tdraft.key,\n\t\t) as Writable<CustomObject | undefined>;\n\n\t\tif (current) {\n\t\t\t// Only check version if it is passed in the draft\n\t\t\tif (draft.version) {\n\t\t\t\tcheckConcurrentModification(current.version, draft.version, current.id);\n\t\t\t} else {\n\t\t\t\tdraft.version = current.version;\n\t\t\t}\n\n\t\t\tif (draft.value !== current.value) {\n\t\t\t\tconst updated = cloneObject(current) as Writable<CustomObject>;\n\t\t\t\tupdated.value = draft.value;\n\t\t\t\tupdated.version += 1;\n\t\t\t\tthis.saveUpdate(context, draft.version, updated);\n\t\t\t\treturn updated;\n\t\t\t}\n\t\t\treturn current;\n\t\t}\n\t\t// If the resource is new the only valid version is 0\n\t\tif (draft.version) {\n\t\t\tthrow new CommercetoolsError<InvalidOperationError>(\n\t\t\t\t{\n\t\t\t\t\tcode: \"InvalidOperation\",\n\t\t\t\t\tmessage: \"version on create must be 0\",\n\t\t\t\t},\n\t\t\t\t400,\n\t\t\t);\n\t\t}\n\t\tconst baseProperties = getBaseResourceProperties();\n\t\tconst resource: CustomObject = {\n\t\t\t...baseProperties,\n\t\t\tcontainer: draft.container,\n\t\t\tkey: draft.key,\n\t\t\tvalue: draft.value,\n\t\t};\n\n\t\tthis.saveNew(context, resource);\n\t\treturn resource;\n\t}\n\n\tgetWithContainerAndKey(\n\t\tcontext: RepositoryContext,\n\t\tcontainer: string,\n\t\tkey: string,\n\t) {\n\t\tconst items = this._storage.all(context.projectKey, this.getTypeId());\n\t\treturn items.find(\n\t\t\t(item) => item.container === container && item.key === key,\n\t\t);\n\t}\n\n\tqueryWithContainer(\n\t\tcontext: RepositoryContext,\n\t\tcontainer: string,\n\t\tparams: QueryParams = {},\n\t) {\n\t\tconst whereClause = params.where || [];\n\t\twhereClause.push(`container=\"${container}\"`);\n\t\tconst result = this._storage.query(context.projectKey, this.getTypeId(), {\n\t\t\t...params,\n\t\t\twhere: whereClause,\n\t\t});\n\n\t\t// @ts-expect-error\n\t\tresult.results = result.results.map((r) =>\n\t\t\tthis.postProcessResource(context, r as CustomObject, {\n\t\t\t\texpand: params.expand,\n\t\t\t}),\n\t\t);\n\t\treturn result;\n\t}\n}\n","import assert from \"node:assert\";\nimport type {\n\tAddress,\n\tBaseAddress,\n\tCustomer,\n\tCustomerAddAddressAction,\n\tCustomerAddBillingAddressIdAction,\n\tCustomerAddShippingAddressIdAction,\n\tCustomerAddStoreAction,\n\tCustomerChangeAddressAction,\n\tCustomerChangeEmailAction,\n\tCustomerRemoveAddressAction,\n\tCustomerRemoveBillingAddressIdAction,\n\tCustomerRemoveShippingAddressIdAction,\n\tCustomerRemoveStoreAction,\n\tCustomerSetAddressCustomFieldAction,\n\tCustomerSetAddressCustomTypeAction,\n\tCustomerSetAuthenticationModeAction,\n\tCustomerSetCompanyNameAction,\n\tCustomerSetCustomerGroupAction,\n\tCustomerSetCustomerNumberAction,\n\tCustomerSetCustomFieldAction,\n\tCustomerSetCustomTypeAction,\n\tCustomerSetDateOfBirthAction,\n\tCustomerSetDefaultBillingAddressAction,\n\tCustomerSetDefaultShippingAddressAction,\n\tCustomerSetExternalIdAction,\n\tCustomerSetFirstNameAction,\n\tCustomerSetKeyAction,\n\tCustomerSetLastNameAction,\n\tCustomerSetLocaleAction,\n\tCustomerSetMiddleNameAction,\n\tCustomerSetSalutationAction,\n\tCustomerSetStoresAction,\n\tCustomerSetTitleAction,\n\tCustomerSetVatIdAction,\n\tCustomerUpdateAction,\n\tInvalidInputError,\n\tInvalidJsonInputError,\n\tInvalidOperationError,\n} from \"@commercetools/platform-sdk\";\nimport { CommercetoolsError } from \"#src/exceptions.ts\";\nimport { generateRandomString } from \"#src/helpers.ts\";\nimport { hashPassword } from \"#src/lib/password.ts\";\nimport type { Writable } from \"#src/types.ts\";\nimport type { UpdateHandlerInterface } from \"../abstract.ts\";\nimport { AbstractUpdateHandler, type RepositoryContext } from \"../abstract.ts\";\nimport { createAddress, createCustomFields } from \"../helpers.ts\";\n\nexport class CustomerUpdateHandler\n\textends AbstractUpdateHandler\n\timplements Partial<UpdateHandlerInterface<Customer, CustomerUpdateAction>>\n{\n\taddAddress(\n\t\t_context: RepositoryContext,\n\t\tresource: Writable<Customer>,\n\t\t{ address }: CustomerAddAddressAction,\n\t) {\n\t\tresource.addresses.push({\n\t\t\t...address,\n\t\t\tid: address.id ?? generateRandomString(5),\n\t\t} as BaseAddress);\n\t}\n\n\taddBillingAddressId(\n\t\t_context: RepositoryContext,\n\t\tresource: Writable<Customer>,\n\t\t{ addressId, addressKey }: CustomerAddBillingAddressIdAction,\n\t) {\n\t\tconst address = this._findAddress(resource, addressId, addressKey, true);\n\t\tassert(address?.id); // always true since we set required to true\n\n\t\tif (resource.billingAddressIds === undefined) {\n\t\t\tresource.billingAddressIds = [];\n\t\t}\n\n\t\tif (!resource.billingAddressIds.includes(address.id)) {\n\t\t\tresource.billingAddressIds.push(address.id);\n\t\t}\n\t}\n\n\taddShippingAddressId(\n\t\t_context: RepositoryContext,\n\t\tresource: Writable<Customer>,\n\t\t{ addressId, addressKey }: CustomerAddShippingAddressIdAction,\n\t) {\n\t\tconst address = this._findAddress(resource, addressId, addressKey, true);\n\t\tassert(address?.id); // always true since we set required to true\n\n\t\tif (resource.shippingAddressIds === undefined) {\n\t\t\tresource.shippingAddressIds = [];\n\t\t}\n\n\t\tif (!resource.shippingAddressIds.includes(address.id)) {\n\t\t\tresource.shippingAddressIds.push(address.id);\n\t\t}\n\t\treturn resource;\n\t}\n\n\taddStore(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Customer>,\n\t\taction: CustomerAddStoreAction,\n\t) {\n\t\tthrow new Error(\"Method not implemented.\");\n\t}\n\n\tchangeAddress(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Customer>,\n\t\t{ addressId, addressKey, address }: CustomerChangeAddressAction,\n\t) {\n\t\tconst current = this._findAddress(resource, addressId, addressKey, true);\n\t\tassert(current?.id); // always true since we set required to true\n\n\t\tconst oldAddressIndex = resource.addresses.findIndex(\n\t\t\t(a) => a.id === current.id,\n\t\t);\n\n\t\tconst newAddress = createAddress(\n\t\t\t{ ...address, id: current.id },\n\t\t\tcontext.projectKey,\n\t\t\tthis._storage,\n\t\t);\n\n\t\tif (newAddress) {\n\t\t\tresource.addresses[oldAddressIndex] = newAddress;\n\t\t}\n\t}\n\n\tchangeEmail(\n\t\t_context: RepositoryContext,\n\t\tresource: Writable<Customer>,\n\t\t{ email }: CustomerChangeEmailAction,\n\t) {\n\t\tresource.email = email;\n\t}\n\n\tremoveAddress(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Customer>,\n\t\taction: CustomerRemoveAddressAction,\n\t) {\n\t\tconst address = this._findAddress(\n\t\t\tresource,\n\t\t\taction.addressId,\n\t\t\taction.addressKey,\n\t\t\ttrue,\n\t\t);\n\t\tassert(address?.id); // always true since we set required to true\n\t\tresource.addresses = resource.addresses.filter((a) => a.id !== address.id);\n\t}\n\n\tremoveBillingAddressId(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Customer>,\n\t\taction: CustomerRemoveBillingAddressIdAction,\n\t) {\n\t\tconst address = this._findAddress(\n\t\t\tresource,\n\t\t\taction.addressId,\n\t\t\taction.addressKey,\n\t\t\ttrue,\n\t\t);\n\t\tassert(address?.id); // always true since we set required to true\n\t\tresource.billingAddressIds = resource.billingAddressIds?.filter(\n\t\t\t(id) => id !== address.id,\n\t\t);\n\t\tif (resource.defaultBillingAddressId === address.id) {\n\t\t\tresource.defaultBillingAddressId = undefined;\n\t\t}\n\t}\n\n\tremoveShippingAddressId(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Customer>,\n\t\taction: CustomerRemoveShippingAddressIdAction,\n\t) {\n\t\tconst address = this._findAddress(\n\t\t\tresource,\n\t\t\taction.addressId,\n\t\t\taction.addressKey,\n\t\t\ttrue,\n\t\t);\n\t\tassert(address?.id); // always true since we set required to true\n\t\tresource.shippingAddressIds = resource.shippingAddressIds?.filter(\n\t\t\t(id) => id !== address.id,\n\t\t);\n\t\tif (resource.defaultShippingAddressId === address.id) {\n\t\t\tresource.defaultShippingAddressId = undefined;\n\t\t}\n\t}\n\n\tremoveStore(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Customer>,\n\t\taction: CustomerRemoveStoreAction,\n\t) {\n\t\tthrow new Error(\"Method not implemented.\");\n\t}\n\n\tsetAddressCustomField(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Customer>,\n\t\taction: CustomerSetAddressCustomFieldAction,\n\t) {\n\t\tthrow new Error(\"Method not implemented.\");\n\t}\n\n\tsetAddressCustomType(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Customer>,\n\t\taction: CustomerSetAddressCustomTypeAction,\n\t) {\n\t\tthrow new Error(\"Method not implemented.\");\n\t}\n\n\tsetAuthenticationMode(\n\t\t_context: RepositoryContext,\n\t\tresource: Writable<Customer>,\n\t\t{ authMode, password }: CustomerSetAuthenticationModeAction,\n\t) {\n\t\tif (resource.authenticationMode === authMode) {\n\t\t\tthrow new CommercetoolsError<InvalidInputError>(\n\t\t\t\t{\n\t\t\t\t\tcode: \"InvalidInput\",\n\t\t\t\t\tmessage: `The customer is already using the '${resource.authenticationMode}' authentication mode.`,\n\t\t\t\t},\n\t\t\t\t400,\n\t\t\t);\n\t\t}\n\t\tresource.authenticationMode = authMode;\n\t\tif (authMode === \"ExternalAuth\") {\n\t\t\tresource.password = undefined;\n\t\t\treturn;\n\t\t}\n\t\tif (authMode === \"Password\") {\n\t\t\tresource.password = password ? hashPassword(password) : undefined;\n\t\t\treturn;\n\t\t}\n\t\tthrow new CommercetoolsError<InvalidJsonInputError>(\n\t\t\t{\n\t\t\t\tcode: \"InvalidJsonInput\",\n\t\t\t\tmessage: \"Request body does not contain valid JSON.\",\n\t\t\t\tdetailedErrorMessage: `actions -> authMode: Invalid enum value: '${authMode}'. Expected one of: 'Password','ExternalAuth'`,\n\t\t\t},\n\t\t\t400,\n\t\t);\n\t}\n\n\tsetCompanyName(\n\t\t_context: RepositoryContext,\n\t\tresource: Writable<Customer>,\n\t\t{ companyName }: CustomerSetCompanyNameAction,\n\t) {\n\t\tresource.companyName = companyName;\n\t}\n\n\tsetCustomerGroup(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Customer>,\n\t\taction: CustomerSetCustomerGroupAction,\n\t) {\n\t\tif (!action.customerGroup) {\n\t\t\tthrow new CommercetoolsError<InvalidOperationError>(\n\t\t\t\t{\n\t\t\t\t\tcode: \"InvalidOperation\",\n\t\t\t\t\tmessage: \"CustomerGroup is required.\",\n\t\t\t\t},\n\t\t\t\t400,\n\t\t\t);\n\t\t}\n\n\t\tconst group = this._storage.getByResourceIdentifier<\"customer-group\">(\n\t\t\tcontext.projectKey,\n\t\t\taction.customerGroup,\n\t\t);\n\n\t\tresource.customerGroup = {\n\t\t\ttypeId: \"customer-group\",\n\t\t\tid: group.id,\n\t\t};\n\t}\n\n\tsetCustomerNumber(\n\t\t_context: RepositoryContext,\n\t\tresource: Writable<Customer>,\n\t\t{ customerNumber }: CustomerSetCustomerNumberAction,\n\t) {\n\t\tif (resource.customerNumber) {\n\t\t\tthrow new Error(\n\t\t\t\t\"A Customer number already exists and cannot be set again.\",\n\t\t\t);\n\t\t}\n\t\tresource.customerNumber = customerNumber;\n\t}\n\n\tsetCustomField(\n\t\t_context: RepositoryContext,\n\t\tresource: Writable<Customer>,\n\t\t{ name, value }: CustomerSetCustomFieldAction,\n\t) {\n\t\tif (!resource.custom) {\n\t\t\tthrow new Error(\"Resource has no custom field\");\n\t\t}\n\t\tresource.custom.fields[name] = value;\n\t}\n\n\tsetCustomType(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Customer>,\n\t\t{ type, fields }: CustomerSetCustomTypeAction,\n\t) {\n\t\tif (type) {\n\t\t\tresource.custom = createCustomFields(\n\t\t\t\t{ type, fields },\n\t\t\t\tcontext.projectKey,\n\t\t\t\tthis._storage,\n\t\t\t);\n\t\t} else {\n\t\t\tresource.custom = undefined;\n\t\t}\n\t}\n\n\tsetDateOfBirth(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Customer>,\n\t\taction: CustomerSetDateOfBirthAction,\n\t) {\n\t\tresource.dateOfBirth = action.dateOfBirth;\n\t}\n\n\tsetDefaultBillingAddress(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Customer>,\n\t\taction: CustomerSetDefaultBillingAddressAction,\n\t) {\n\t\tconst address = this._findAddress(\n\t\t\tresource,\n\t\t\taction.addressId,\n\t\t\taction.addressKey,\n\t\t\ttrue,\n\t\t);\n\t\tassert(address?.id); // always true since we set required to true\n\n\t\tresource.defaultBillingAddressId = address.id;\n\t\tif (resource.billingAddressIds === undefined) {\n\t\t\tresource.billingAddressIds = [];\n\t\t}\n\t\tif (!resource.billingAddressIds.includes(address.id)) {\n\t\t\tresource.billingAddressIds.push(address.id);\n\t\t}\n\t}\n\n\tsetDefaultShippingAddress(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Customer>,\n\t\taction: CustomerSetDefaultShippingAddressAction,\n\t) {\n\t\tconst address = this._findAddress(\n\t\t\tresource,\n\t\t\taction.addressId,\n\t\t\taction.addressKey,\n\t\t\ttrue,\n\t\t);\n\t\tassert(address?.id); // always true since we set required to true\n\n\t\tresource.defaultShippingAddressId = address.id;\n\t\tif (resource.shippingAddressIds === undefined) {\n\t\t\tresource.shippingAddressIds = [];\n\t\t}\n\t\tif (!resource.shippingAddressIds.includes(address.id)) {\n\t\t\tresource.shippingAddressIds.push(address.id);\n\t\t}\n\t}\n\n\tsetExternalId(\n\t\t_context: RepositoryContext,\n\t\tresource: Writable<Customer>,\n\t\t{ externalId }: CustomerSetExternalIdAction,\n\t) {\n\t\tresource.externalId = externalId;\n\t}\n\n\tsetFirstName(\n\t\t_context: RepositoryContext,\n\t\tresource: Writable<Customer>,\n\t\t{ firstName }: CustomerSetFirstNameAction,\n\t) {\n\t\tresource.firstName = firstName;\n\t}\n\n\tsetKey(\n\t\t_context: RepositoryContext,\n\t\tresource: Writable<Customer>,\n\t\t{ key }: CustomerSetKeyAction,\n\t) {\n\t\tresource.key = key;\n\t}\n\n\tsetLastName(\n\t\t_context: RepositoryContext,\n\t\tresource: Writable<Customer>,\n\t\t{ lastName }: CustomerSetLastNameAction,\n\t) {\n\t\tresource.lastName = lastName;\n\t}\n\n\tsetLocale(\n\t\t_context: RepositoryContext,\n\t\tresource: Writable<Customer>,\n\t\t{ locale }: CustomerSetLocaleAction,\n\t) {\n\t\tresource.locale = locale;\n\t}\n\n\tsetMiddleName(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Customer>,\n\t\taction: CustomerSetMiddleNameAction,\n\t) {\n\t\tresource.middleName = action.middleName;\n\t}\n\n\tsetSalutation(\n\t\t_context: RepositoryContext,\n\t\tresource: Writable<Customer>,\n\t\t{ salutation }: CustomerSetSalutationAction,\n\t) {\n\t\tresource.salutation = salutation;\n\t}\n\n\tsetStores(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Customer>,\n\t\taction: CustomerSetStoresAction,\n\t) {\n\t\tthrow new Error(\"Method not implemented.\");\n\t}\n\n\tsetTitle(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Customer>,\n\t\taction: CustomerSetTitleAction,\n\t) {\n\t\tresource.title = action.title;\n\t}\n\n\tsetVatId(\n\t\t_context: RepositoryContext,\n\t\tresource: Writable<Customer>,\n\t\t{ vatId }: CustomerSetVatIdAction,\n\t) {\n\t\tresource.vatId = vatId;\n\t}\n\n\tprivate _findAddress(\n\t\tresource: Writable<Customer>,\n\t\taddressId: string | undefined,\n\t\taddressKey: string | undefined,\n\t\trequired = false,\n\t): Address | undefined {\n\t\tif (addressKey) {\n\t\t\tconst address = resource.addresses.find((a) => a.key === addressKey);\n\t\t\tif (!address) {\n\t\t\t\tthrow new CommercetoolsError<InvalidOperationError>(\n\t\t\t\t\t{\n\t\t\t\t\t\tcode: \"InvalidOperation\",\n\t\t\t\t\t\tmessage: `Customer does not contain an address with the key ${addressKey}.`,\n\t\t\t\t\t},\n\t\t\t\t\t400,\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn address;\n\t\t}\n\n\t\tif (addressId) {\n\t\t\tconst address = resource.addresses.find((a) => a.id === addressId);\n\t\t\tif (!address) {\n\t\t\t\tthrow new CommercetoolsError<InvalidOperationError>(\n\t\t\t\t\t{\n\t\t\t\t\t\tcode: \"InvalidOperation\",\n\t\t\t\t\t\tmessage: `Customer does not contain an address with the id ${addressId}.`,\n\t\t\t\t\t},\n\t\t\t\t\t400,\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn address;\n\t\t}\n\n\t\tif (required) {\n\t\t\tthrow new CommercetoolsError<InvalidOperationError>(\n\t\t\t\t{\n\t\t\t\t\tcode: \"InvalidOperation\",\n\t\t\t\t\tmessage: \"One of address 'addressId' or 'addressKey' is required.\",\n\t\t\t\t},\n\t\t\t\t400,\n\t\t\t);\n\t\t}\n\t}\n}\n","import type {\n\tAddress,\n\tCustomer,\n\tCustomerCreatePasswordResetToken,\n\tCustomerDraft,\n\tCustomerResetPassword,\n\tCustomerToken,\n\tDuplicateFieldError,\n\tInvalidInputError,\n\tMyCustomerResetPassword,\n\tResourceNotFoundError,\n\tStore,\n\tStoreKeyReference,\n\tStoreResourceIdentifier,\n} from \"@commercetools/platform-sdk\";\nimport type { Config } from \"#src/config.ts\";\nimport { CommercetoolsError } from \"#src/exceptions.ts\";\nimport {\n\tgenerateRandomString,\n\tgetBaseResourceProperties,\n} from \"#src/helpers.ts\";\nimport {\n\tcreateEmailVerifyToken,\n\tcreatePasswordResetToken,\n\thashPassword,\n\tvalidatePasswordResetToken,\n} from \"#src/lib/password.ts\";\nimport type { ResourceMap, ShallowWritable, Writable } from \"#src/types.ts\";\nimport {\n\tAbstractResourceRepository,\n\ttype RepositoryContext,\n} from \"../abstract.ts\";\nimport { createCustomFields } from \"../helpers.ts\";\nimport { CustomerUpdateHandler } from \"./actions.ts\";\n\nexport class CustomerRepository extends AbstractResourceRepository<\"customer\"> {\n\tconstructor(config: Config) {\n\t\tsuper(\"customer\", config);\n\t\tthis.actions = new CustomerUpdateHandler(config.storage);\n\t}\n\n\tcreate(context: RepositoryContext, draft: CustomerDraft): Customer {\n\t\t// Check uniqueness\n\t\tconst results = this._storage.query(context.projectKey, this.getTypeId(), {\n\t\t\twhere: [`lowercaseEmail=\"${draft.email.toLowerCase()}\"`],\n\t\t});\n\t\tif (results.count > 0) {\n\t\t\tthrow new CommercetoolsError<any>({\n\t\t\t\tcode: \"CustomerAlreadyExists\",\n\t\t\t\tstatusCode: 400,\n\t\t\t\tmessage:\n\t\t\t\t\t\"There is already an existing customer with the provided email.\",\n\t\t\t\terrors: [\n\t\t\t\t\t{\n\t\t\t\t\t\tcode: \"DuplicateField\",\n\t\t\t\t\t\tmessage: `Customer with email '${draft.email}' already exists.`,\n\t\t\t\t\t\tduplicateValue: draft.email,\n\t\t\t\t\t\tfield: \"email\",\n\t\t\t\t\t} as DuplicateFieldError,\n\t\t\t\t],\n\t\t\t});\n\t\t}\n\n\t\tconst addresses: Address[] =\n\t\t\tdraft.addresses?.map((address) => ({\n\t\t\t\t...address,\n\t\t\t\tid: generateRandomString(5),\n\t\t\t})) ?? [];\n\n\t\tconst lookupAdressId = (\n\t\t\taddresses: Address[],\n\t\t\taddressId: number,\n\t\t): string => {\n\t\t\tif (addressId < addresses.length) {\n\t\t\t\tconst id = addresses[addressId].id;\n\t\t\t\tif (!id) {\n\t\t\t\t\tthrow new Error(\"Address ID is missing\");\n\t\t\t\t}\n\t\t\t\treturn id;\n\t\t\t}\n\t\t\tthrow new CommercetoolsError<InvalidInputError>({\n\t\t\t\tcode: \"InvalidInput\",\n\t\t\t\tmessage: `Address with ID '${addressId}' not found.`,\n\t\t\t\terrors: [\n\t\t\t\t\t{\n\t\t\t\t\t\tcode: \"InvalidInput\",\n\t\t\t\t\t\tmessage: `Address with ID '${addressId}' not found.`,\n\t\t\t\t\t\tfield: \"addressId\",\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t});\n\t\t};\n\n\t\tconst defaultBillingAddressId =\n\t\t\tdraft.defaultBillingAddress !== undefined\n\t\t\t\t? lookupAdressId(addresses, draft.defaultBillingAddress)\n\t\t\t\t: undefined;\n\t\tconst defaultShippingAddressId =\n\t\t\tdraft.defaultShippingAddress !== undefined\n\t\t\t\t? lookupAdressId(addresses, draft.defaultShippingAddress)\n\t\t\t\t: undefined;\n\t\tconst shippingAddressIds =\n\t\t\tdraft.shippingAddresses?.map((addressId) =>\n\t\t\t\tlookupAdressId(addresses, addressId),\n\t\t\t) ?? [];\n\t\tconst billingAddressIds =\n\t\t\tdraft.billingAddresses?.map((addressId) =>\n\t\t\t\tlookupAdressId(addresses, addressId),\n\t\t\t) ?? [];\n\n\t\tlet storesForCustomer: StoreKeyReference[] = [];\n\n\t\tif (draft.stores && draft.stores.length > 0) {\n\t\t\tstoresForCustomer = this.storeReferenceToStoreKeyReference(\n\t\t\t\tdraft.stores,\n\t\t\t\tcontext.projectKey,\n\t\t\t);\n\t\t}\n\n\t\tconst resource: Customer = {\n\t\t\t...getBaseResourceProperties(),\n\t\t\tkey: draft.key,\n\t\t\tauthenticationMode: draft.authenticationMode || \"Password\",\n\t\t\tfirstName: draft.firstName,\n\t\t\tlastName: draft.lastName,\n\t\t\tmiddleName: draft.middleName,\n\t\t\ttitle: draft.title,\n\t\t\tdateOfBirth: draft.dateOfBirth,\n\t\t\tcompanyName: draft.companyName,\n\t\t\temail: draft.email.toLowerCase(),\n\t\t\tlowercaseEmail: draft.email.toLowerCase(),\n\t\t\tpassword: draft.password ? hashPassword(draft.password) : undefined,\n\t\t\tisEmailVerified: draft.isEmailVerified || false,\n\t\t\taddresses: addresses,\n\t\t\tcustomerNumber: draft.customerNumber,\n\t\t\texternalId: draft.externalId,\n\t\t\tdefaultBillingAddressId: defaultBillingAddressId,\n\t\t\tdefaultShippingAddressId: defaultShippingAddressId,\n\t\t\tshippingAddressIds: shippingAddressIds,\n\t\t\tbillingAddressIds: billingAddressIds,\n\t\t\tcustom: createCustomFields(\n\t\t\t\tdraft.custom,\n\t\t\t\tcontext.projectKey,\n\t\t\t\tthis._storage,\n\t\t\t),\n\t\t\tstores: storesForCustomer,\n\t\t} satisfies unknown as Customer;\n\n\t\treturn this.saveNew(context, resource);\n\t}\n\n\tsaveUpdate(\n\t\tcontext: RepositoryContext,\n\t\tversion: number,\n\t\tresource: ShallowWritable<ResourceMap[\"customer\"]>,\n\t): ShallowWritable<ResourceMap[\"customer\"]> {\n\t\t// Also update lowercaseEmail attribute\n\t\tconst updatedResource: Customer = {\n\t\t\t...resource,\n\t\t\tlowercaseEmail: resource.email.toLowerCase(),\n\t\t} satisfies unknown as Customer;\n\n\t\treturn super.saveUpdate(context, version, updatedResource);\n\t}\n\n\tpasswordResetToken(\n\t\tcontext: RepositoryContext,\n\t\trequest: CustomerCreatePasswordResetToken,\n\t): CustomerToken {\n\t\tconst results = this._storage.query(context.projectKey, this.getTypeId(), {\n\t\t\twhere: [`email=\"${request.email.toLocaleLowerCase()}\"`],\n\t\t});\n\t\tif (results.count === 0) {\n\t\t\tthrow new CommercetoolsError<ResourceNotFoundError>({\n\t\t\t\tcode: \"ResourceNotFound\",\n\t\t\t\tmessage: `The Customer with ID '${request.email}' was not found.`,\n\t\t\t});\n\t\t}\n\n\t\tconst ttlMinutes = request.ttlMinutes ?? 34560; // 34560 is CT default\n\n\t\tconst expiresAt = new Date(Date.now() + ttlMinutes * 60 * 1000);\n\t\tconst customer = results.results[0] as Customer;\n\t\tconst rest = getBaseResourceProperties();\n\n\t\tconst token = createPasswordResetToken(customer, expiresAt);\n\n\t\treturn {\n\t\t\tid: rest.id,\n\t\t\tcreatedAt: rest.createdAt,\n\t\t\tlastModifiedAt: rest.lastModifiedAt,\n\t\t\tcustomerId: customer.id,\n\t\t\texpiresAt: expiresAt.toISOString(),\n\t\t\tvalue: token,\n\t\t\tinvalidateOlderTokens: request.invalidateOlderTokens || false,\n\t\t};\n\t}\n\n\tpasswordReset(\n\t\tcontext: RepositoryContext,\n\t\tresetPassword: CustomerResetPassword | MyCustomerResetPassword,\n\t) {\n\t\tconst { newPassword, tokenValue } = resetPassword;\n\n\t\tconst customerId = validatePasswordResetToken(tokenValue);\n\t\tif (!customerId) {\n\t\t\tthrow new CommercetoolsError<ResourceNotFoundError>({\n\t\t\t\tcode: \"ResourceNotFound\",\n\t\t\t\tmessage: `The Customer with ID 'Token(${tokenValue})' was not found.`,\n\t\t\t});\n\t\t}\n\n\t\tconst customer = this._storage.get(\n\t\t\tcontext.projectKey,\n\t\t\t\"customer\",\n\t\t\tcustomerId,\n\t\t) as Writable<Customer> | undefined;\n\n\t\tif (!customer) {\n\t\t\tthrow new CommercetoolsError<ResourceNotFoundError>({\n\t\t\t\tcode: \"ResourceNotFound\",\n\t\t\t\tmessage: `The Customer with ID 'Token(${tokenValue})' was not found.`,\n\t\t\t});\n\t\t}\n\n\t\tcustomer.password = hashPassword(newPassword);\n\t\tcustomer.version += 1;\n\n\t\t// Update storage\n\t\tthis._storage.add(context.projectKey, \"customer\", customer);\n\t\treturn customer;\n\t}\n\n\tverifyEmailToken(context: RepositoryContext, id: string): CustomerToken {\n\t\tconst results = this._storage.query(context.projectKey, this.getTypeId(), {\n\t\t\twhere: [`id=\"${id.toLocaleLowerCase()}\"`],\n\t\t});\n\t\tif (results.count === 0) {\n\t\t\tthrow new CommercetoolsError<ResourceNotFoundError>({\n\t\t\t\tcode: \"ResourceNotFound\",\n\t\t\t\tmessage: `The Customer with ID '${id}' was not found.`,\n\t\t\t});\n\t\t}\n\t\tconst expiresAt = new Date(Date.now() + 30 * 60);\n\t\tconst customer = results.results[0] as Customer;\n\t\tconst rest = getBaseResourceProperties();\n\n\t\tconst token = createEmailVerifyToken(customer);\n\t\treturn {\n\t\t\tid: rest.id,\n\t\t\tcreatedAt: rest.createdAt,\n\t\t\tlastModifiedAt: rest.lastModifiedAt,\n\t\t\tcustomerId: customer.id,\n\t\t\texpiresAt: expiresAt.toISOString(),\n\t\t\tvalue: token,\n\t\t\tinvalidateOlderTokens: false,\n\t\t};\n\t}\n\n\tprivate storeReferenceToStoreKeyReference(\n\t\tdraftStores: StoreResourceIdentifier[],\n\t\tprojectKey: string,\n\t): StoreKeyReference[] {\n\t\tconst storeIds = draftStores\n\t\t\t.map((storeReference) => storeReference.id)\n\t\t\t.filter(Boolean);\n\n\t\tlet stores: Store[] = [];\n\n\t\tif (storeIds.length > 0) {\n\t\t\tstores = this._storage.query(projectKey, \"store\", {\n\t\t\t\twhere: storeIds.map((id) => `id=\"${id}\"`),\n\t\t\t}).results;\n\n\t\t\tif (storeIds.length !== stores.length) {\n\t\t\t\tthrow new CommercetoolsError<ResourceNotFoundError>({\n\t\t\t\t\tcode: \"ResourceNotFound\",\n\t\t\t\t\tmessage: `Store with ID '${storeIds.find((id) => !stores.some((store) => store.id === id))}' was not found.`,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\treturn draftStores.map((storeReference) => ({\n\t\t\ttypeId: \"store\",\n\t\t\tkey:\n\t\t\t\tstoreReference.key ??\n\t\t\t\t(stores.find((store) => store.id === storeReference.id)?.key as string),\n\t\t}));\n\t}\n}\n","import type {\n\tCustomerGroup,\n\tCustomerGroupChangeNameAction,\n\tCustomerGroupDraft,\n\tCustomerGroupSetCustomFieldAction,\n\tCustomerGroupSetCustomTypeAction,\n\tCustomerGroupSetKeyAction,\n\tCustomerGroupUpdateAction,\n} from \"@commercetools/platform-sdk\";\nimport type { Config } from \"#src/config.ts\";\nimport { getBaseResourceProperties } from \"../helpers.ts\";\nimport type { Writable } from \"../types.ts\";\nimport type { UpdateHandlerInterface } from \"./abstract.ts\";\nimport {\n\tAbstractResourceRepository,\n\tAbstractUpdateHandler,\n\ttype RepositoryContext,\n} from \"./abstract.ts\";\nimport { createCustomFields } from \"./helpers.ts\";\n\nexport class CustomerGroupRepository extends AbstractResourceRepository<\"customer-group\"> {\n\tconstructor(config: Config) {\n\t\tsuper(\"customer-group\", config);\n\t\tthis.actions = new CustomerGroupUpdateHandler(config.storage);\n\t}\n\n\tcreate(context: RepositoryContext, draft: CustomerGroupDraft): CustomerGroup {\n\t\tconst resource: CustomerGroup = {\n\t\t\t...getBaseResourceProperties(),\n\t\t\tkey: draft.key,\n\t\t\tname: draft.groupName,\n\t\t\tcustom: createCustomFields(\n\t\t\t\tdraft.custom,\n\t\t\t\tcontext.projectKey,\n\t\t\t\tthis._storage,\n\t\t\t),\n\t\t};\n\t\treturn this.saveNew(context, resource);\n\t}\n}\n\nclass CustomerGroupUpdateHandler\n\textends AbstractUpdateHandler\n\timplements UpdateHandlerInterface<CustomerGroup, CustomerGroupUpdateAction>\n{\n\tchangeName(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<CustomerGroup>,\n\t\t{ name }: CustomerGroupChangeNameAction,\n\t) {\n\t\tresource.name = name;\n\t}\n\n\tsetCustomField(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<CustomerGroup>,\n\t\t{ name, value }: CustomerGroupSetCustomFieldAction,\n\t) {\n\t\tif (!resource.custom) {\n\t\t\treturn;\n\t\t}\n\t\tif (value === null) {\n\t\t\tdelete resource.custom.fields[name];\n\t\t} else {\n\t\t\tresource.custom.fields[name] = value;\n\t\t}\n\t}\n\n\tsetCustomType(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<CustomerGroup>,\n\t\t{ type, fields }: CustomerGroupSetCustomTypeAction,\n\t) {\n\t\tif (type) {\n\t\t\tresource.custom = createCustomFields(\n\t\t\t\t{ type, fields },\n\t\t\t\tcontext.projectKey,\n\t\t\t\tthis._storage,\n\t\t\t);\n\t\t} else {\n\t\t\tresource.custom = undefined;\n\t\t}\n\t}\n\n\tsetKey(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<CustomerGroup>,\n\t\t{ key }: CustomerGroupSetKeyAction,\n\t) {\n\t\tresource.key = key;\n\t}\n}\n","import type {\n\tCartDiscountReference,\n\tDiscountCode,\n\tDiscountCodeChangeCartDiscountsAction,\n\tDiscountCodeChangeIsActiveAction,\n\tDiscountCodeSetCartPredicateAction,\n\tDiscountCodeSetCustomFieldAction,\n\tDiscountCodeSetCustomTypeAction,\n\tDiscountCodeSetDescriptionAction,\n\tDiscountCodeSetMaxApplicationsAction,\n\tDiscountCodeSetMaxApplicationsPerCustomerAction,\n\tDiscountCodeSetNameAction,\n\tDiscountCodeSetValidFromAction,\n\tDiscountCodeSetValidFromAndUntilAction,\n\tDiscountCodeSetValidUntilAction,\n\tDiscountCodeUpdateAction,\n} from \"@commercetools/platform-sdk\";\nimport type { Writable } from \"#src/types.ts\";\nimport type { UpdateHandlerInterface } from \"../abstract.ts\";\nimport { AbstractUpdateHandler, type RepositoryContext } from \"../abstract.ts\";\nimport { createCustomFields } from \"../helpers.ts\";\n\nexport class DiscountCodeUpdateHandler\n\textends AbstractUpdateHandler\n\timplements\n\t\tPartial<UpdateHandlerInterface<DiscountCode, DiscountCodeUpdateAction>>\n{\n\tchangeCartDiscounts(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<DiscountCode>,\n\t\t{ cartDiscounts }: DiscountCodeChangeCartDiscountsAction,\n\t) {\n\t\tresource.cartDiscounts = cartDiscounts.map(\n\t\t\t(obj): CartDiscountReference => ({\n\t\t\t\ttypeId: \"cart-discount\",\n\t\t\t\tid: obj.id!,\n\t\t\t}),\n\t\t);\n\t}\n\n\tchangeIsActive(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<DiscountCode>,\n\t\t{ isActive }: DiscountCodeChangeIsActiveAction,\n\t) {\n\t\tresource.isActive = isActive;\n\t}\n\n\tsetCartPredicate(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<DiscountCode>,\n\t\t{ cartPredicate }: DiscountCodeSetCartPredicateAction,\n\t) {\n\t\tresource.cartPredicate = cartPredicate;\n\t}\n\n\tsetCustomField(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<DiscountCode>,\n\t\t{ name, value }: DiscountCodeSetCustomFieldAction,\n\t) {\n\t\tif (!resource.custom) {\n\t\t\treturn;\n\t\t}\n\t\tif (value === null) {\n\t\t\tdelete resource.custom.fields[name];\n\t\t} else {\n\t\t\tresource.custom.fields[name] = value;\n\t\t}\n\t}\n\n\tsetCustomType(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<DiscountCode>,\n\t\t{ type, fields }: DiscountCodeSetCustomTypeAction,\n\t) {\n\t\tif (type) {\n\t\t\tresource.custom = createCustomFields(\n\t\t\t\t{ type, fields },\n\t\t\t\tcontext.projectKey,\n\t\t\t\tthis._storage,\n\t\t\t);\n\t\t} else {\n\t\t\tresource.custom = undefined;\n\t\t}\n\t}\n\n\tsetDescription(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<DiscountCode>,\n\t\t{ description }: DiscountCodeSetDescriptionAction,\n\t) {\n\t\tresource.description = description;\n\t}\n\n\tsetMaxApplications(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<DiscountCode>,\n\t\t{ maxApplications }: DiscountCodeSetMaxApplicationsAction,\n\t) {\n\t\tresource.maxApplications = maxApplications;\n\t}\n\n\tsetMaxApplicationsPerCustomer(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<DiscountCode>,\n\t\t{\n\t\t\tmaxApplicationsPerCustomer,\n\t\t}: DiscountCodeSetMaxApplicationsPerCustomerAction,\n\t) {\n\t\tresource.maxApplicationsPerCustomer = maxApplicationsPerCustomer;\n\t}\n\n\tsetName(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<DiscountCode>,\n\t\t{ name }: DiscountCodeSetNameAction,\n\t) {\n\t\tresource.name = name;\n\t}\n\n\tsetValidFrom(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<DiscountCode>,\n\t\t{ validFrom }: DiscountCodeSetValidFromAction,\n\t) {\n\t\tresource.validFrom = validFrom;\n\t}\n\n\tsetValidFromAndUntil(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<DiscountCode>,\n\t\t{ validFrom, validUntil }: DiscountCodeSetValidFromAndUntilAction,\n\t) {\n\t\tresource.validFrom = validFrom;\n\t\tresource.validUntil = validUntil;\n\t}\n\n\tsetValidUntil(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<DiscountCode>,\n\t\t{ validUntil }: DiscountCodeSetValidUntilAction,\n\t) {\n\t\tresource.validUntil = validUntil;\n\t}\n}\n","import type {\n\tCartDiscountReference,\n\tDiscountCode,\n\tDiscountCodeDraft,\n} from \"@commercetools/platform-sdk\";\nimport type { Config } from \"#src/config.ts\";\nimport { getBaseResourceProperties } from \"#src/helpers.ts\";\nimport {\n\tAbstractResourceRepository,\n\ttype RepositoryContext,\n} from \"../abstract.ts\";\nimport { createCustomFields } from \"../helpers.ts\";\nimport { DiscountCodeUpdateHandler } from \"./actions.ts\";\n\nexport class DiscountCodeRepository extends AbstractResourceRepository<\"discount-code\"> {\n\tconstructor(config: Config) {\n\t\tsuper(\"discount-code\", config);\n\t\tthis.actions = new DiscountCodeUpdateHandler(config.storage);\n\t}\n\n\tcreate(context: RepositoryContext, draft: DiscountCodeDraft): DiscountCode {\n\t\tconst resource: DiscountCode = {\n\t\t\t...getBaseResourceProperties(),\n\t\t\tapplicationVersion: 1,\n\t\t\tcartDiscounts: draft.cartDiscounts.map(\n\t\t\t\t(obj): CartDiscountReference => ({\n\t\t\t\t\ttypeId: \"cart-discount\",\n\t\t\t\t\tid: obj.id!,\n\t\t\t\t}),\n\t\t\t),\n\t\t\tcartPredicate: draft.cartPredicate,\n\t\t\tcode: draft.code,\n\t\t\tdescription: draft.description,\n\t\t\tgroups: draft.groups || [],\n\t\t\tisActive: draft.isActive || true,\n\t\t\tname: draft.name,\n\t\t\treferences: [],\n\t\t\tvalidFrom: draft.validFrom,\n\t\t\tvalidUntil: draft.validUntil,\n\t\t\tmaxApplications: draft.maxApplications,\n\t\t\tmaxApplicationsPerCustomer: draft.maxApplicationsPerCustomer,\n\t\t\tcustom: createCustomFields(\n\t\t\t\tdraft.custom,\n\t\t\t\tcontext.projectKey,\n\t\t\t\tthis._storage,\n\t\t\t),\n\t\t};\n\t\treturn this.saveNew(context, resource);\n\t}\n}\n","import type {\n\tDiscountGroup,\n\tDiscountGroupSetDescriptionAction,\n\tDiscountGroupSetKeyAction,\n\tDiscountGroupSetNameAction,\n\tDiscountGroupSetSortOrderAction,\n\tDiscountGroupUpdateAction,\n} from \"@commercetools/platform-sdk\";\nimport type { Writable } from \"#src/types.ts\";\nimport type { UpdateHandlerInterface } from \"../abstract.ts\";\nimport { AbstractUpdateHandler, type RepositoryContext } from \"../abstract.ts\";\n\nexport class DiscountGroupUpdateHandler\n\textends AbstractUpdateHandler\n\timplements\n\t\tPartial<UpdateHandlerInterface<DiscountGroup, DiscountGroupUpdateAction>>\n{\n\tsetDescription(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<DiscountGroup>,\n\t\t{ description }: DiscountGroupSetDescriptionAction,\n\t) {\n\t\tresource.description = description;\n\t}\n\n\tsetKey(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<DiscountGroup>,\n\t\t{ key }: DiscountGroupSetKeyAction,\n\t) {\n\t\tresource.key = key;\n\t}\n\n\tsetName(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<DiscountGroup>,\n\t\t{ name }: DiscountGroupSetNameAction,\n\t) {\n\t\tresource.name = name;\n\t}\n\n\tsetSortOrder(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<DiscountGroup>,\n\t\t{ sortOrder }: DiscountGroupSetSortOrderAction,\n\t) {\n\t\tresource.sortOrder = sortOrder;\n\t}\n}\n","import type {\n\tDiscountGroup,\n\tDiscountGroupDraft,\n} from \"@commercetools/platform-sdk\";\nimport type { Config } from \"#src/config.ts\";\nimport { getBaseResourceProperties } from \"#src/helpers.ts\";\nimport {\n\tAbstractResourceRepository,\n\ttype RepositoryContext,\n} from \"../abstract.ts\";\nimport { DiscountGroupUpdateHandler } from \"./actions.ts\";\n\nexport class DiscountGroupRepository extends AbstractResourceRepository<\"discount-group\"> {\n\tconstructor(config: Config) {\n\t\tsuper(\"discount-group\", config);\n\t\tthis.actions = new DiscountGroupUpdateHandler(config.storage);\n\t}\n\n\tcreate(context: RepositoryContext, draft: DiscountGroupDraft): DiscountGroup {\n\t\tconst resource: DiscountGroup = {\n\t\t\t...getBaseResourceProperties(),\n\t\t\tdescription: draft.description,\n\t\t\tname: draft.name,\n\t\t\tkey: draft.key,\n\t\t\tsortOrder: draft.sortOrder,\n\t\t\tisActive: true,\n\t\t};\n\t\treturn this.saveNew(context, resource);\n\t}\n}\n","import { cloneObject } from \"../helpers.ts\";\n\nexport const maskSecretValue = <T>(resource: T, path: string): T => {\n\tconst parts = path.split(\".\");\n\tconst clone = cloneObject(resource) as any;\n\tlet val = clone;\n\n\tconst target = parts.pop();\n\tfor (let i = 0; i < parts.length; i++) {\n\t\tconst part = parts[i];\n\t\tval = val[part];\n\n\t\tif (val === undefined) {\n\t\t\treturn resource;\n\t\t}\n\t}\n\n\tif (val && target && val[target]) {\n\t\tval[target] = \"****\";\n\t}\n\treturn clone;\n};\n","import type {\n\tExtension,\n\tExtensionChangeDestinationAction,\n\tExtensionChangeTriggersAction,\n\tExtensionDraft,\n\tExtensionSetKeyAction,\n\tExtensionSetTimeoutInMsAction,\n\tExtensionUpdateAction,\n} from \"@commercetools/platform-sdk\";\nimport type { Config } from \"#src/config.ts\";\nimport { getBaseResourceProperties } from \"../helpers.ts\";\nimport { maskSecretValue } from \"../lib/masking.ts\";\nimport type { Writable } from \"../types.ts\";\nimport type { UpdateHandlerInterface } from \"./abstract.ts\";\nimport {\n\tAbstractResourceRepository,\n\tAbstractUpdateHandler,\n\ttype RepositoryContext,\n} from \"./abstract.ts\";\n\nexport class ExtensionRepository extends AbstractResourceRepository<\"extension\"> {\n\tconstructor(config: Config) {\n\t\tsuper(\"extension\", config);\n\t\tthis.actions = new ExtensionUpdateHandler(config.storage);\n\t}\n\n\tcreate(context: RepositoryContext, draft: ExtensionDraft): Extension {\n\t\tconst resource: Extension = {\n\t\t\t...getBaseResourceProperties(),\n\t\t\tkey: draft.key,\n\t\t\ttimeoutInMs: draft.timeoutInMs,\n\t\t\tdestination: draft.destination,\n\t\t\ttriggers: draft.triggers,\n\t\t};\n\t\treturn this.saveNew(context, resource);\n\t}\n\n\tpostProcessResource(\n\t\tcontext: RepositoryContext,\n\t\tresource: Extension,\n\t): Extension {\n\t\tif (resource) {\n\t\t\tconst extension = resource as Extension;\n\t\t\tif (\n\t\t\t\textension.destination.type === \"HTTP\" &&\n\t\t\t\textension.destination.authentication?.type === \"AuthorizationHeader\"\n\t\t\t) {\n\t\t\t\treturn maskSecretValue(\n\t\t\t\t\textension,\n\t\t\t\t\t\"destination.authentication.headerValue\",\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (extension.destination.type === \"AWSLambda\") {\n\t\t\t\treturn maskSecretValue(resource, \"destination.accessSecret\");\n\t\t\t}\n\t\t}\n\t\treturn resource;\n\t}\n}\n\nclass ExtensionUpdateHandler\n\textends AbstractUpdateHandler\n\timplements UpdateHandlerInterface<Extension, ExtensionUpdateAction>\n{\n\tchangeDestination(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Extension>,\n\t\taction: ExtensionChangeDestinationAction,\n\t): void {\n\t\tresource.destination = action.destination;\n\t}\n\n\tchangeTriggers(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Extension>,\n\t\taction: ExtensionChangeTriggersAction,\n\t): void {\n\t\tresource.triggers = action.triggers;\n\t}\n\n\tsetKey(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Extension>,\n\t\taction: ExtensionSetKeyAction,\n\t): void {\n\t\tresource.key = action.key;\n\t}\n\n\tsetTimeoutInMs(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Extension>,\n\t\taction: ExtensionSetTimeoutInMsAction,\n\t): void {\n\t\tresource.timeoutInMs = action.timeoutInMs;\n\t}\n}\n","import type {\n\tInventoryEntry,\n\tInventoryEntryChangeQuantityAction,\n\tInventoryEntryRemoveQuantityAction,\n\tInventoryEntrySetCustomFieldAction,\n\tInventoryEntrySetCustomTypeAction,\n\tInventoryEntrySetExpectedDeliveryAction,\n\tInventoryEntrySetRestockableInDaysAction,\n\tInventoryEntryUpdateAction,\n} from \"@commercetools/platform-sdk\";\nimport type { Writable } from \"#src/types.ts\";\nimport type { UpdateHandlerInterface } from \"../abstract.ts\";\nimport { AbstractUpdateHandler, type RepositoryContext } from \"../abstract.ts\";\n\nexport class InventoryEntryUpdateHandler\n\textends AbstractUpdateHandler\n\timplements\n\t\tPartial<UpdateHandlerInterface<InventoryEntry, InventoryEntryUpdateAction>>\n{\n\tchangeQuantity(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<InventoryEntry>,\n\t\t{ quantity }: InventoryEntryChangeQuantityAction,\n\t) {\n\t\tresource.quantityOnStock = quantity;\n\t\t// don't know active reservations so just set to same value\n\t\tresource.availableQuantity = quantity;\n\t}\n\n\tremoveQuantity(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<InventoryEntry>,\n\t\t{ quantity }: InventoryEntryRemoveQuantityAction,\n\t) {\n\t\tconst newQuantity = Math.max(0, resource.quantityOnStock - quantity);\n\t\tresource.quantityOnStock = newQuantity;\n\t\t// don't know active reservations so just set to same value\n\t\tresource.availableQuantity = newQuantity;\n\t}\n\n\tsetCustomField(\n\t\tcontext: RepositoryContext,\n\t\tresource: InventoryEntry,\n\t\t{ name, value }: InventoryEntrySetCustomFieldAction,\n\t) {\n\t\tif (!resource.custom) {\n\t\t\tthrow new Error(\"Resource has no custom field\");\n\t\t}\n\t\tresource.custom.fields[name] = value;\n\t}\n\n\tsetCustomType(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<InventoryEntry>,\n\t\t{ type, fields }: InventoryEntrySetCustomTypeAction,\n\t) {\n\t\tif (!type) {\n\t\t\tresource.custom = undefined;\n\t\t} else {\n\t\t\tconst resolvedType = this._storage.getByResourceIdentifier(\n\t\t\t\tcontext.projectKey,\n\t\t\t\ttype,\n\t\t\t);\n\t\t\tif (!resolvedType) {\n\t\t\t\tthrow new Error(`Type ${type} not found`);\n\t\t\t}\n\n\t\t\tresource.custom = {\n\t\t\t\ttype: {\n\t\t\t\t\ttypeId: \"type\",\n\t\t\t\t\tid: resolvedType.id,\n\t\t\t\t},\n\t\t\t\tfields: fields || {},\n\t\t\t};\n\t\t}\n\t}\n\n\tsetExpectedDelivery(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<InventoryEntry>,\n\t\t{ expectedDelivery }: InventoryEntrySetExpectedDeliveryAction,\n\t) {\n\t\tresource.expectedDelivery = new Date(expectedDelivery!).toISOString();\n\t}\n\n\tsetRestockableInDays(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<InventoryEntry>,\n\t\t{ restockableInDays }: InventoryEntrySetRestockableInDaysAction,\n\t) {\n\t\tresource.restockableInDays = restockableInDays;\n\t}\n}\n","import type {\n\tInventoryEntry,\n\tInventoryEntryDraft,\n} from \"@commercetools/platform-sdk\";\nimport type { Config } from \"#src/config.ts\";\nimport { getBaseResourceProperties } from \"#src/helpers.ts\";\nimport {\n\tAbstractResourceRepository,\n\ttype RepositoryContext,\n} from \"../abstract.ts\";\nimport { createCustomFields } from \"../helpers.ts\";\nimport { InventoryEntryUpdateHandler } from \"./actions.ts\";\n\nexport class InventoryEntryRepository extends AbstractResourceRepository<\"inventory-entry\"> {\n\tconstructor(config: Config) {\n\t\tsuper(\"inventory-entry\", config);\n\t\tthis.actions = new InventoryEntryUpdateHandler(config.storage);\n\t}\n\n\tcreate(\n\t\tcontext: RepositoryContext,\n\t\tdraft: InventoryEntryDraft,\n\t): InventoryEntry {\n\t\tconst resource: InventoryEntry = {\n\t\t\t...getBaseResourceProperties(),\n\t\t\tsku: draft.sku,\n\t\t\tquantityOnStock: draft.quantityOnStock,\n\t\t\tavailableQuantity: draft.quantityOnStock,\n\t\t\texpectedDelivery: draft.expectedDelivery,\n\t\t\trestockableInDays: draft.restockableInDays,\n\t\t\tsupplyChannel: {\n\t\t\t\t...draft.supplyChannel,\n\t\t\t\ttypeId: \"channel\",\n\t\t\t\tid: draft.supplyChannel?.id ?? \"\",\n\t\t\t},\n\t\t\tcustom: createCustomFields(\n\t\t\t\tdraft.custom,\n\t\t\t\tcontext.projectKey,\n\t\t\t\tthis._storage,\n\t\t\t),\n\t\t};\n\t\treturn this.saveNew(context, resource);\n\t}\n}\n","import type {\n\tCustomer,\n\tInvalidCurrentPasswordError,\n\tMyCustomerChangePassword,\n\tMyCustomerEmailVerify,\n\tResourceNotFoundError,\n} from \"@commercetools/platform-sdk\";\nimport { CommercetoolsError } from \"#src/exceptions.ts\";\nimport { hashPassword, validateEmailVerifyToken } from \"../lib/password.ts\";\nimport type { Writable } from \"../types.ts\";\nimport type { RepositoryContext } from \"./abstract.ts\";\nimport { CustomerRepository } from \"./customer/index.ts\";\n\nexport class MyCustomerRepository extends CustomerRepository {\n\tchangePassword(\n\t\tcontext: RepositoryContext,\n\t\tchangePassword: MyCustomerChangePassword,\n\t) {\n\t\tconst { currentPassword, newPassword } = changePassword;\n\t\tconst encodedPassword = hashPassword(currentPassword);\n\n\t\tconst result = this._storage.query(context.projectKey, \"customer\", {\n\t\t\twhere: [`password = \"${encodedPassword}\"`],\n\t\t});\n\t\tif (result.count === 0) {\n\t\t\tthrow new CommercetoolsError<InvalidCurrentPasswordError>({\n\t\t\t\tcode: \"InvalidCurrentPassword\",\n\t\t\t\tmessage: \"Account with the given credentials not found.\",\n\t\t\t});\n\t\t}\n\n\t\tconst customer = result.results[0] as Writable<Customer>;\n\t\tif (customer.password !== hashPassword(currentPassword)) {\n\t\t\tthrow new CommercetoolsError<InvalidCurrentPasswordError>({\n\t\t\t\tcode: \"InvalidCurrentPassword\",\n\t\t\t\tmessage: \"The current password is invalid.\",\n\t\t\t});\n\t\t}\n\n\t\tcustomer.password = hashPassword(newPassword);\n\t\tcustomer.version += 1;\n\n\t\t// Update storage\n\t\tthis._storage.add(context.projectKey, \"customer\", customer);\n\t\treturn customer;\n\t}\n\n\tconfirmEmail(\n\t\tcontext: RepositoryContext,\n\t\tresetPassword: MyCustomerEmailVerify,\n\t) {\n\t\tconst { tokenValue } = resetPassword;\n\n\t\tconst customerId = validateEmailVerifyToken(tokenValue);\n\t\tif (!customerId) {\n\t\t\tthrow new CommercetoolsError<ResourceNotFoundError>({\n\t\t\t\tcode: \"ResourceNotFound\",\n\t\t\t\tmessage: `The Customer with ID 'Token(${tokenValue})' was not found.`,\n\t\t\t});\n\t\t}\n\n\t\tconst customer = this._storage.get(\n\t\t\tcontext.projectKey,\n\t\t\t\"customer\",\n\t\t\tcustomerId,\n\t\t) as Writable<Customer> | undefined;\n\n\t\tif (!customer) {\n\t\t\tthrow new CommercetoolsError<ResourceNotFoundError>({\n\t\t\t\tcode: \"ResourceNotFound\",\n\t\t\t\tmessage: `The Customer with ID 'Token(${tokenValue})' was not found.`,\n\t\t\t});\n\t\t}\n\n\t\tcustomer.isEmailVerified = true;\n\t\tcustomer.version += 1;\n\n\t\t// Update storage\n\t\tthis._storage.add(context.projectKey, \"customer\", customer);\n\t\treturn customer;\n\t}\n\n\tdeleteMe(context: RepositoryContext): Customer | undefined {\n\t\t// grab the first customer you can find for now. In the future we should\n\t\t// use the customer id from the scope of the token\n\t\tconst results = this._storage.query(\n\t\t\tcontext.projectKey,\n\t\t\tthis.getTypeId(),\n\t\t\t{},\n\t\t);\n\n\t\tif (results.count > 0) {\n\t\t\treturn this.delete(context, results.results[0].id) as Customer;\n\t\t}\n\n\t\treturn;\n\t}\n\n\tgetMe(context: RepositoryContext): Customer | undefined {\n\t\t// grab the first customer you can find for now. In the future we should\n\t\t// use the customer id from the scope of the token\n\t\tconst results = this._storage.query(\n\t\t\tcontext.projectKey,\n\t\t\tthis.getTypeId(),\n\t\t\t{},\n\t\t);\n\n\t\tif (results.count > 0) {\n\t\t\treturn results.results[0] as Customer;\n\t\t}\n\n\t\treturn;\n\t}\n}\n","import assert from \"node:assert\";\nimport type {\n\tCartReference,\n\tMyOrderFromCartDraft,\n\tOrder,\n} from \"@commercetools/platform-sdk\";\nimport type { RepositoryContext } from \"./abstract.ts\";\nimport { OrderRepository } from \"./order/index.ts\";\n\nexport class MyOrderRepository extends OrderRepository {\n\tcreate(context: RepositoryContext, draft: MyOrderFromCartDraft): Order {\n\t\tassert(draft.id, \"draft.id is missing\");\n\t\tconst cartIdentifier = {\n\t\t\tid: draft.id,\n\t\t\ttypeId: \"cart\",\n\t\t} as CartReference;\n\t\treturn this.createFromCart(context, cartIdentifier);\n\t}\n}\n","import type {\n\tOrderEdit,\n\tOrderEditDraft,\n\tOrderEditResult,\n} from \"@commercetools/platform-sdk\";\nimport type { Config } from \"#src/config.ts\";\nimport { getBaseResourceProperties } from \"../helpers.ts\";\nimport type { RepositoryContext } from \"./abstract.ts\";\nimport { AbstractResourceRepository } from \"./abstract.ts\";\n\nexport class OrderEditRepository extends AbstractResourceRepository<\"order-edit\"> {\n\tconstructor(config: Config) {\n\t\tsuper(\"order-edit\", config);\n\t}\n\n\tcreate(context: RepositoryContext, draft: OrderEditDraft): OrderEdit {\n\t\tconst resource: OrderEdit = {\n\t\t\t...getBaseResourceProperties(),\n\t\t\tstagedActions: draft.stagedActions ?? [],\n\t\t\tresource: draft.resource,\n\t\t\tresult: {\n\t\t\t\ttype: \"NotProcessed\",\n\t\t\t} as OrderEditResult,\n\t\t};\n\t\treturn this.saveNew(context, resource);\n\t}\n}\n","import type {\n\tTransaction,\n\tTransactionDraft,\n} from \"@commercetools/platform-sdk\";\nimport { v4 as uuidv4 } from \"uuid\";\nimport type { AbstractStorage } from \"#src/storage/index.ts\";\nimport type { RepositoryContext } from \"../abstract.ts\";\nimport { createCentPrecisionMoney, createCustomFields } from \"../helpers.ts\";\n\nexport const transactionFromTransactionDraft = (\n\tcontext: RepositoryContext,\n\tstorage: AbstractStorage,\n\tdraft: TransactionDraft,\n): Transaction => ({\n\t...draft,\n\tid: uuidv4(),\n\tamount: createCentPrecisionMoney(draft.amount),\n\tcustom: createCustomFields(draft.custom, context.projectKey, storage),\n\tstate: draft.state ?? \"Initial\", // Documented as default\n});\n","import type {\n\tCustomerReference,\n\tPayment,\n\tPaymentAddInterfaceInteractionAction,\n\tPaymentAddTransactionAction,\n\tPaymentChangeAmountPlannedAction,\n\tPaymentChangeTransactionInteractionIdAction,\n\tPaymentChangeTransactionStateAction,\n\tPaymentChangeTransactionTimestampAction,\n\tPaymentSetAnonymousIdAction,\n\tPaymentSetCustomerAction,\n\tPaymentSetCustomFieldAction,\n\tPaymentSetCustomTypeAction,\n\tPaymentSetInterfaceIdAction,\n\tPaymentSetKeyAction,\n\tPaymentSetMethodInfoAction,\n\tPaymentSetMethodInfoCustomFieldAction,\n\tPaymentSetMethodInfoCustomTypeAction,\n\tPaymentSetMethodInfoInterfaceAccountAction,\n\tPaymentSetMethodInfoInterfaceAction,\n\tPaymentSetMethodInfoMethodAction,\n\tPaymentSetMethodInfoNameAction,\n\tPaymentSetMethodInfoTokenAction,\n\tPaymentSetStatusInterfaceCodeAction,\n\tPaymentSetStatusInterfaceTextAction,\n\tPaymentSetTransactionCustomFieldAction,\n\tPaymentSetTransactionCustomTypeAction,\n\tPaymentTransitionStateAction,\n\tPaymentUpdateAction,\n\tState,\n\tTransaction,\n} from \"@commercetools/platform-sdk\";\nimport type { Writable } from \"#src/types.ts\";\nimport type { RepositoryContext, UpdateHandlerInterface } from \"../abstract.ts\";\nimport { AbstractUpdateHandler } from \"../abstract.ts\";\nimport {\n\tcreateCentPrecisionMoney,\n\tcreateCustomFields,\n\tgetReferenceFromResourceIdentifier,\n} from \"../helpers.ts\";\nimport { transactionFromTransactionDraft } from \"./helpers.ts\";\n\nexport class PaymentUpdateHandler\n\textends AbstractUpdateHandler\n\timplements UpdateHandlerInterface<Payment, PaymentUpdateAction>\n{\n\taddInterfaceInteraction(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Payment>,\n\t\t{ type, fields }: PaymentAddInterfaceInteractionAction,\n\t) {\n\t\tresource.interfaceInteractions.push(\n\t\t\tcreateCustomFields({ type, fields }, context.projectKey, this._storage)!,\n\t\t);\n\t}\n\n\taddTransaction(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Payment>,\n\t\t{ transaction }: PaymentAddTransactionAction,\n\t) {\n\t\tresource.transactions = [\n\t\t\t...resource.transactions,\n\t\t\ttransactionFromTransactionDraft(context, this._storage, transaction),\n\t\t];\n\t}\n\n\tchangeAmountPlanned(\n\t\t_context: RepositoryContext,\n\t\tresource: Writable<Payment>,\n\t\t{ amount }: PaymentChangeAmountPlannedAction,\n\t) {\n\t\tresource.amountPlanned = createCentPrecisionMoney(amount);\n\t}\n\n\tchangeTransactionInteractionId(\n\t\t_context: RepositoryContext,\n\t\tresource: Writable<Payment>,\n\t\t{\n\t\t\ttransactionId,\n\t\t\tinteractionId,\n\t\t}: PaymentChangeTransactionInteractionIdAction,\n\t) {\n\t\tconst transaction = resource.transactions.find(\n\t\t\t(e: Transaction) => e.id === transactionId,\n\t\t);\n\t\tif (transaction) {\n\t\t\ttransaction.interactionId = interactionId;\n\t\t}\n\t}\n\n\tchangeTransactionState(\n\t\t_context: RepositoryContext,\n\t\tresource: Writable<Payment>,\n\t\t{ transactionId, state }: PaymentChangeTransactionStateAction,\n\t) {\n\t\tconst index = resource.transactions.findIndex(\n\t\t\t(e: Transaction) => e.id === transactionId,\n\t\t);\n\t\tconst updatedTransaction: Transaction = {\n\t\t\t...resource.transactions[index],\n\t\t\tstate,\n\t\t};\n\t\tresource.transactions[index] = updatedTransaction;\n\t}\n\n\tchangeTransactionTimestamp(\n\t\t_context: RepositoryContext,\n\t\tresource: Writable<Payment>,\n\t\t{ transactionId, timestamp }: PaymentChangeTransactionTimestampAction,\n\t) {\n\t\tconst transaction = resource.transactions.find(\n\t\t\t(e: Transaction) => e.id === transactionId,\n\t\t);\n\t\tif (transaction) {\n\t\t\ttransaction.timestamp = timestamp;\n\t\t}\n\t}\n\n\tsetAnonymousId(\n\t\t_context: RepositoryContext,\n\t\tresource: Writable<Payment>,\n\t\t{ anonymousId }: PaymentSetAnonymousIdAction,\n\t) {\n\t\tresource.anonymousId = anonymousId;\n\t\tresource.customer = undefined;\n\t}\n\n\tsetCustomer(\n\t\t_context: RepositoryContext,\n\t\tresource: Writable<Payment>,\n\t\t{ customer }: PaymentSetCustomerAction,\n\t) {\n\t\tif (customer) {\n\t\t\tconst c = getReferenceFromResourceIdentifier<CustomerReference>(\n\t\t\t\tcustomer,\n\t\t\t\t_context.projectKey,\n\t\t\t\tthis._storage,\n\t\t\t);\n\t\t\tresource.customer = c;\n\t\t\tresource.anonymousId = undefined;\n\t\t}\n\t}\n\n\tsetCustomField(\n\t\tcontext: RepositoryContext,\n\t\tresource: Payment,\n\t\t{ name, value }: PaymentSetCustomFieldAction,\n\t) {\n\t\tif (!resource.custom) {\n\t\t\tthrow new Error(\"Resource has no custom field\");\n\t\t}\n\n\t\tresource.custom.fields[name] = value;\n\t}\n\n\tsetCustomType(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Payment>,\n\t\t{ type, fields }: PaymentSetCustomTypeAction,\n\t) {\n\t\tif (!type) {\n\t\t\tresource.custom = undefined;\n\t\t} else {\n\t\t\tconst resolvedType = this._storage.getByResourceIdentifier(\n\t\t\t\tcontext.projectKey,\n\t\t\t\ttype,\n\t\t\t);\n\t\t\tif (!resolvedType) {\n\t\t\t\tthrow new Error(`Type ${type} not found`);\n\t\t\t}\n\n\t\t\tresource.custom = {\n\t\t\t\ttype: {\n\t\t\t\t\ttypeId: \"type\",\n\t\t\t\t\tid: resolvedType.id,\n\t\t\t\t},\n\t\t\t\tfields: fields ?? {},\n\t\t\t};\n\t\t}\n\t}\n\n\tsetInterfaceId(\n\t\t_context: RepositoryContext,\n\t\tresource: Writable<Payment>,\n\t\t{ interfaceId }: PaymentSetInterfaceIdAction,\n\t) {\n\t\tresource.interfaceId = interfaceId;\n\t}\n\n\tsetKey(\n\t\t_context: RepositoryContext,\n\t\tresource: Writable<Payment>,\n\t\t{ key }: PaymentSetKeyAction,\n\t) {\n\t\tresource.key = key;\n\t}\n\n\tsetMethodInfoInterface(\n\t\t_context: RepositoryContext,\n\t\tresource: Writable<Payment>,\n\t\targs: PaymentSetMethodInfoInterfaceAction,\n\t) {\n\t\tresource.paymentMethodInfo.paymentInterface = args.interface;\n\t}\n\n\tsetMethodInfoMethod(\n\t\t_context: RepositoryContext,\n\t\tresource: Writable<Payment>,\n\t\t{ method }: PaymentSetMethodInfoMethodAction,\n\t) {\n\t\tresource.paymentMethodInfo.method = method;\n\t}\n\n\tsetMethodInfoName(\n\t\t_context: RepositoryContext,\n\t\tresource: Writable<Payment>,\n\t\t{ name }: PaymentSetMethodInfoNameAction,\n\t) {\n\t\tresource.paymentMethodInfo.name = name;\n\t}\n\n\tsetStatusInterfaceCode(\n\t\t_context: RepositoryContext,\n\t\tresource: Writable<Payment>,\n\t\t{ interfaceCode }: PaymentSetStatusInterfaceCodeAction,\n\t) {\n\t\tresource.paymentStatus.interfaceCode = interfaceCode;\n\t}\n\n\tsetStatusInterfaceText(\n\t\t_context: RepositoryContext,\n\t\tresource: Writable<Payment>,\n\t\t{ interfaceText }: PaymentSetStatusInterfaceTextAction,\n\t) {\n\t\tresource.paymentStatus.interfaceText = interfaceText;\n\t}\n\n\tsetTransactionCustomField(\n\t\t_context: RepositoryContext,\n\t\tresource: Writable<Payment>,\n\t\t{ transactionId, name, value }: PaymentSetTransactionCustomFieldAction,\n\t) {\n\t\tconst transaction = resource.transactions.find(\n\t\t\t(e: Transaction) => e.id === transactionId,\n\t\t);\n\t\tif (transaction) {\n\t\t\tif (!transaction.custom) {\n\t\t\t\tthrow new Error(\"Transaction has no custom field\");\n\t\t\t}\n\n\t\t\ttransaction.custom.fields[name] = value;\n\t\t}\n\t}\n\n\tsetTransactionCustomType(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Payment>,\n\t\t{ transactionId, type, fields }: PaymentSetTransactionCustomTypeAction,\n\t) {\n\t\tconst transaction = resource.transactions.find(\n\t\t\t(e: Transaction) => e.id === transactionId,\n\t\t);\n\t\tif (transaction) {\n\t\t\tif (!type) {\n\t\t\t\ttransaction.custom = undefined;\n\t\t\t} else {\n\t\t\t\tconst resolvedType = this._storage.getByResourceIdentifier(\n\t\t\t\t\tcontext.projectKey,\n\t\t\t\t\ttype,\n\t\t\t\t);\n\t\t\t\tif (!resolvedType) {\n\t\t\t\t\tthrow new Error(`Type ${type} not found`);\n\t\t\t\t}\n\n\t\t\t\ttransaction.custom = {\n\t\t\t\t\ttype: {\n\t\t\t\t\t\ttypeId: \"type\",\n\t\t\t\t\t\tid: resolvedType.id,\n\t\t\t\t\t},\n\t\t\t\t\tfields: fields ?? {},\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\t}\n\n\ttransitionState(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Payment>,\n\t\t{ state }: PaymentTransitionStateAction,\n\t) {\n\t\tconst stateObj = this._storage.getByResourceIdentifier(\n\t\t\tcontext.projectKey,\n\t\t\tstate,\n\t\t) as State | null;\n\n\t\tif (!stateObj) {\n\t\t\tthrow new Error(`State ${state} not found`);\n\t\t}\n\n\t\tresource.paymentStatus.state = {\n\t\t\ttypeId: \"state\",\n\t\t\tid: stateObj.id,\n\t\t\tobj: stateObj,\n\t\t};\n\t}\n\n\tsetMethodInfo(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Payment>,\n\t\t{\n\t\t\tpaymentInterface,\n\t\t\tmethod,\n\t\t\tname,\n\t\t\tinterfaceAccount,\n\t\t\ttoken,\n\t\t}: PaymentSetMethodInfoAction,\n\t) {\n\t\tif (paymentInterface !== undefined) {\n\t\t\tresource.paymentMethodInfo.paymentInterface = paymentInterface;\n\t\t}\n\t\tif (method !== undefined) {\n\t\t\tresource.paymentMethodInfo.method = method;\n\t\t}\n\t\tif (name !== undefined) {\n\t\t\tresource.paymentMethodInfo.name = name;\n\t\t}\n\t\tif (interfaceAccount !== undefined) {\n\t\t\tresource.paymentMethodInfo.interfaceAccount = interfaceAccount;\n\t\t}\n\t\tif (token !== undefined) {\n\t\t\tresource.paymentMethodInfo.token = token;\n\t\t}\n\t}\n\n\tsetMethodInfoCustomField(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Payment>,\n\t\t{ name, value }: PaymentSetMethodInfoCustomFieldAction,\n\t) {\n\t\tif (!resource.paymentMethodInfo.custom) {\n\t\t\tthrow new Error(\"PaymentMethodInfo has no custom field\");\n\t\t}\n\n\t\tresource.paymentMethodInfo.custom.fields[name] = value;\n\t}\n\n\tsetMethodInfoCustomType(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Payment>,\n\t\t{ type, fields }: PaymentSetMethodInfoCustomTypeAction,\n\t) {\n\t\tif (!type) {\n\t\t\tresource.paymentMethodInfo.custom = undefined;\n\t\t} else {\n\t\t\tconst resolvedType = this._storage.getByResourceIdentifier(\n\t\t\t\tcontext.projectKey,\n\t\t\t\ttype,\n\t\t\t);\n\t\t\tif (!resolvedType) {\n\t\t\t\tthrow new Error(`Type ${type} not found`);\n\t\t\t}\n\n\t\t\tresource.paymentMethodInfo.custom = {\n\t\t\t\ttype: {\n\t\t\t\t\ttypeId: \"type\",\n\t\t\t\t\tid: resolvedType.id,\n\t\t\t\t},\n\t\t\t\tfields: fields ?? {},\n\t\t\t};\n\t\t}\n\t}\n\n\tsetMethodInfoInterfaceAccount(\n\t\t_context: RepositoryContext,\n\t\tresource: Writable<Payment>,\n\t\t{ interfaceAccount }: PaymentSetMethodInfoInterfaceAccountAction,\n\t) {\n\t\tresource.paymentMethodInfo.interfaceAccount = interfaceAccount;\n\t}\n\n\tsetMethodInfoToken(\n\t\t_context: RepositoryContext,\n\t\tresource: Writable<Payment>,\n\t\t{ token }: PaymentSetMethodInfoTokenAction,\n\t) {\n\t\tresource.paymentMethodInfo.token = token;\n\t}\n}\n","import type {\n\tPayment,\n\tPaymentDraft,\n\tStateReference,\n} from \"@commercetools/platform-sdk\";\nimport type { Config } from \"#src/config.ts\";\nimport { getBaseResourceProperties } from \"#src/helpers.ts\";\nimport type { RepositoryContext } from \"../abstract.ts\";\nimport { AbstractResourceRepository } from \"../abstract.ts\";\nimport {\n\tcreateCentPrecisionMoney,\n\tcreateCustomFields,\n\tgetReferenceFromResourceIdentifier,\n} from \"../helpers.ts\";\nimport { PaymentUpdateHandler } from \"./actions.ts\";\nimport { transactionFromTransactionDraft } from \"./helpers.ts\";\n\nexport class PaymentRepository extends AbstractResourceRepository<\"payment\"> {\n\tconstructor(config: Config) {\n\t\tsuper(\"payment\", config);\n\t\tthis.actions = new PaymentUpdateHandler(this._storage);\n\t}\n\n\tcreate(context: RepositoryContext, draft: PaymentDraft): Payment {\n\t\tconst resource: Payment = {\n\t\t\t...getBaseResourceProperties(),\n\t\t\tkey: draft.key,\n\t\t\tamountPlanned: createCentPrecisionMoney(draft.amountPlanned),\n\t\t\tpaymentMethodInfo: { ...draft.paymentMethodInfo!, custom: undefined },\n\t\t\tpaymentStatus: draft.paymentStatus\n\t\t\t\t? {\n\t\t\t\t\t\t...draft.paymentStatus,\n\t\t\t\t\t\tstate: draft.paymentStatus.state\n\t\t\t\t\t\t\t? getReferenceFromResourceIdentifier<StateReference>(\n\t\t\t\t\t\t\t\t\tdraft.paymentStatus.state,\n\t\t\t\t\t\t\t\t\tcontext.projectKey,\n\t\t\t\t\t\t\t\t\tthis._storage,\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t: undefined,\n\t\t\t\t\t}\n\t\t\t\t: {},\n\t\t\ttransactions: (draft.transactions || []).map((t) =>\n\t\t\t\ttransactionFromTransactionDraft(context, this._storage, t),\n\t\t\t),\n\t\t\tinterfaceInteractions: (draft.interfaceInteractions || []).map(\n\t\t\t\t(interaction) =>\n\t\t\t\t\tcreateCustomFields(interaction, context.projectKey, this._storage)!,\n\t\t\t),\n\t\t\tcustom: createCustomFields(\n\t\t\t\tdraft.custom,\n\t\t\t\tcontext.projectKey,\n\t\t\t\tthis._storage,\n\t\t\t),\n\t\t};\n\n\t\treturn this.saveNew(context, resource);\n\t}\n}\n","import type {\n\tReview,\n\tReviewRatingStatistics,\n} from \"@commercetools/platform-sdk\";\nimport type { AbstractStorage } from \"../storage/index.ts\";\n\nexport class ReviewStatisticsService {\n\tconstructor(private _storage: AbstractStorage) {}\n\n\tcalculateProductReviewStatistics(\n\t\tprojectKey: string,\n\t\tproductId: string,\n\t): ReviewRatingStatistics | undefined {\n\t\t// Get all reviews for this product\n\t\tconst allReviews = this._storage.all(projectKey, \"review\") as Review[];\n\t\tconst productReviews = allReviews.filter(\n\t\t\t(review) =>\n\t\t\t\treview.target?.typeId === \"product\" &&\n\t\t\t\treview.target?.id === productId &&\n\t\t\t\treview.includedInStatistics &&\n\t\t\t\treview.rating !== undefined,\n\t\t);\n\n\t\tif (productReviews.length === 0) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst ratings = productReviews\n\t\t\t.map((review) => review.rating!)\n\t\t\t.filter((rating) => rating !== undefined);\n\n\t\tif (ratings.length === 0) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\t// Calculate statistics\n\t\tconst count = ratings.length;\n\t\tconst sum = ratings.reduce((acc, rating) => acc + rating, 0);\n\t\tconst averageRating = Math.round((sum / count) * 100000) / 100000; // Round to 5 decimals\n\t\tconst highestRating = Math.max(...ratings);\n\t\tconst lowestRating = Math.min(...ratings);\n\n\t\t// Calculate ratings distribution\n\t\tconst ratingsDistribution: { [key: string]: number } = {};\n\t\tfor (const rating of ratings) {\n\t\t\tconst key = rating.toString();\n\t\t\tratingsDistribution[key] = (ratingsDistribution[key] || 0) + 1;\n\t\t}\n\n\t\treturn {\n\t\t\taverageRating,\n\t\t\thighestRating,\n\t\t\tlowestRating,\n\t\t\tcount,\n\t\t\tratingsDistribution,\n\t\t};\n\t}\n}\n","import TokenTypes from \"./token-types\";\n\n/**\n * @private\n */\nexport default class LexerState<T> {\n\tpublic source: string;\n\tpublic position: number;\n\tpublic tokenTypes: TokenTypes<T>;\n\n\tconstructor(source: string, position: number = 0) {\n\t\tthis.source = source;\n\t\tthis.position = position;\n\t}\n\n\tcopy() {\n\t\treturn new LexerState<T>(this.source, this.position);\n\t}\n}\n","import Lexer from \"./lexer\";\n\n/**\n * @typedef {{\n * start: Position,\n * end: Position,\n * }} TokenPosition\n */\n\n/**\n * Represents a token instance\n */\nclass Token<T> {\n\ttype: T;\n\n\tmatch: string;\n\n\tgroups: string[];\n\n\tstart: number;\n\n\tend: number;\n\n\tlexer: Lexer<T>;\n\n\t/* tslint:disable:indent */\n\t/**\n\t * Constructs a token\n\t * @param {T} type The token type\n\t * @param {string} match The string that the lexer consumed to create this token\n\t * @param {string[]} groups Any RegExp groups that accrued during the match\n\t * @param {number} start The string position where this match started\n\t * @param {number} end The string position where this match ends\n\t * @param {Lexer<T>} lexer The parent {@link Lexer}\n\t */\n\tconstructor(\n\t\ttype: T,\n\t\tmatch: string,\n\t\tgroups: string[],\n\t\tstart: number,\n\t\tend: number,\n\t\tlexer: Lexer<T>,\n\t) {\n\t\t/* tslint:enable */\n\t\t/**\n\t\t * The token type\n\t\t * @type {T}\n\t\t */\n\t\tthis.type = type;\n\n\t\t/**\n\t\t * The string that the lexer consumed to create this token\n\t\t * @type {string}\n\t\t */\n\t\tthis.match = match;\n\n\t\t/**\n\t\t * Any RegExp groups that accrued during the match\n\t\t * @type {string[]}\n\t\t */\n\t\tthis.groups = groups;\n\n\t\t/**\n\t\t * The string position where this match started\n\t\t * @type {number}\n\t\t */\n\t\tthis.start = start;\n\n\t\t/**\n\t\t * The string position where this match ends\n\t\t * @type {number}\n\t\t */\n\t\tthis.end = end;\n\n\t\t/**\n\t\t * The parent {@link Lexer}\n\t\t * @type {Lexer<T>}\n\t\t */\n\t\tthis.lexer = lexer;\n\t}\n\n\t/**\n\t * Returns the bounds of this token, each in `{line, column}` format\n\t * @return {TokenPosition}\n\t */\n\tstrpos() {\n\t\tconst start = this.lexer.strpos(this.start);\n\t\tconst end = this.lexer.strpos(this.end);\n\t\treturn { start, end };\n\t}\n\n\t// tslint:disable-next-line prefer-function-over-method\n\tisEof() {\n\t\treturn false;\n\t}\n}\n\nexport default Token;\n\nexport class EOFToken<T> extends Token<T> {\n\tconstructor(lexer: Lexer<T>) {\n\t\tconst end = lexer.source.length;\n\t\tsuper(null as T, \"(eof)\", [], end, end, lexer);\n\t}\n\n\t// tslint:disable-next-line prefer-function-over-method\n\tisEof() {\n\t\treturn true;\n\t}\n}\n\n/**\n * @private\n */\nexport const EOF = (lexer: Lexer<any>) => new EOFToken(lexer);\n","// Thank you, http://stackoverflow.com/a/6969486\nfunction toRegExp(str: string): RegExp {\n\treturn new RegExp(str.replace(/[\\-\\[\\]\\/\\{\\}\\(\\)\\*\\+\\?\\.\\\\\\^\\$\\|]/g, \"\\\\$&\"));\n}\n\nfunction normalize(regex: RegExp | string): RegExp {\n\tif (typeof regex === \"string\") regex = toRegExp(regex);\n\tif (!regex.source.startsWith(\"^\"))\n\t\treturn new RegExp(`^${regex.source}`, regex.flags);\n\telse return regex;\n}\n\nfunction first<T, U>(\n\tarr: T[],\n\tpredicate: (item: T, i: number) => U,\n): { item: T; result: U } | undefined {\n\tlet i = 0;\n\tfor (const item of arr) {\n\t\tconst result = predicate(item, i++);\n\t\tif (result) return { item, result };\n\t}\n}\n\n/**\n * @private\n */\nexport default class TokenTypes<T> {\n\tpublic tokenTypes: {\n\t\ttype: T;\n\t\tregex: RegExp;\n\t\tenabled: boolean;\n\t\tskip: boolean;\n\t}[];\n\n\tconstructor() {\n\t\tthis.tokenTypes = [];\n\t}\n\n\tdisable(type: T): TokenTypes<T> {\n\t\treturn this.enable(type, false);\n\t}\n\n\tenable(type: T, enabled: boolean = true): TokenTypes<T> {\n\t\tthis.tokenTypes\n\t\t\t.filter((t) => t.type == type)\n\t\t\t.forEach((t) => (t.enabled = enabled));\n\t\treturn this;\n\t}\n\n\tisEnabled(type: T) {\n\t\tconst ttypes = this.tokenTypes.filter((tt) => tt.type == type);\n\t\tif (ttypes.length == 0)\n\t\t\tthrow new Error(`Token of type ${type} does not exists`);\n\t\treturn ttypes[0].enabled;\n\t}\n\n\tpeek(source: string, position: number) {\n\t\tconst s = source.substr(position);\n\t\treturn first(\n\t\t\tthis.tokenTypes.filter((tt) => tt.enabled),\n\t\t\t(tt) => {\n\t\t\t\ttt.regex.lastIndex = 0;\n\t\t\t\treturn tt.regex.exec(s);\n\t\t\t},\n\t\t);\n\t}\n\n\ttoken(\n\t\ttype: T,\n\t\tpattern: RegExp | string,\n\t\tskip: boolean = false,\n\t): TokenTypes<T> {\n\t\tthis.tokenTypes.push({\n\t\t\ttype,\n\t\t\tregex: normalize(pattern),\n\t\t\tenabled: true,\n\t\t\tskip,\n\t\t});\n\t\treturn this;\n\t}\n}\n","import LexerState from \"./lexer-state\";\nimport Token, { EOF } from \"./token\";\nimport TokenTypes from \"./token-types\";\n\n/**\n * @typedef {{\n * line: number,\n * column: number,\n * }} Position\n */\n\n/**\n * Lexes a source-string into tokens.\n *\n * @example\n * const lex = perplex('...')\n * .token('ID', /my-id-regex/)\n * .token('(', /\\(/)\n * .token(')', /\\)/)\n * .token('WS', /\\s+/, true) // true means 'skip'\n *\n * while ((let t = lex.next()).type != 'EOF') {\n * console.log(t)\n * }\n * // alternatively:\n * console.log(lex.toArray())\n * // or:\n * console.log(...lex)\n */\nclass Lexer<T> implements Iterable<Token<T>> {\n\t/* tslint:disable:variable-name */\n\tprivate _state: LexerState<T>;\n\n\tprivate _tokenTypes: TokenTypes<T>;\n\t/* tslint:enable */\n\n\t/**\n\t * Creates a new Lexer instance\n\t * @param {string} [source = ''] The source string to operate on.\n\t */\n\tconstructor(source: string = \"\") {\n\t\tthis._state = new LexerState<T>(source);\n\t\tthis._tokenTypes = new TokenTypes<T>();\n\t}\n\n\t//\n\t// Getters/Setters\n\t//\n\n\t/**\n\t * Gets the current lexer position\n\t * @return {number} Returns the position\n\t */\n\tget position() {\n\t\treturn this._state.position;\n\t}\n\n\t/**\n\t * Sets the current lexer position\n\t * @param {number} i The position to move to\n\t */\n\tset position(i: number) {\n\t\tthis._state.position = i;\n\t}\n\n\t/**\n\t * Gets the source the lexer is operating on\n\t * @return {string} Returns the source\n\t */\n\tget source() {\n\t\treturn this._state.source;\n\t}\n\n\t/**\n\t * Sets the source the lexer is operating on\n\t * @param {string} s The source to set\n\t */\n\tset source(s: string) {\n\t\tthis._state = new LexerState<T>(s);\n\t}\n\n\t//\n\t// METHODS\n\t//\n\n\t/**\n\t * Attaches this lexer to another lexer's state\n\t * @param {Lexer<T>} other The other lexer to attach to\n\t */\n\tattachTo(other: Lexer<T>) {\n\t\tthis._state = other._state;\n\t}\n\n\t/**\n\t * Disables a token type\n\t * @param {T} type The token type to disable\n\t * @return {Lexer<T>}\n\t */\n\tdisable(type: T) {\n\t\tthis._tokenTypes.disable(type);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Enables a token type\n\t * @param {T} type The token type to enalbe\n\t * @param {?boolean} [enabled=true] Whether to enable/disable the specified token type\n\t * @return {Lexer<T>}\n\t */\n\tenable(type: T, enabled?: boolean) {\n\t\tthis._tokenTypes.enable(type, enabled);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Like {@link next}, but throws an exception if the next token is\n\t * not of the required type.\n\t * @param {T} type The token type expected from {@link next}\n\t * @return {Token<T>} Returns the {@link Token} on success\n\t */\n\texpect(type: T): Token<T> {\n\t\tconst t = this.next();\n\t\tif (t.type != type) {\n\t\t\tconst pos = t.strpos();\n\t\t\tthrow new Error(\n\t\t\t\t\"Expected \" +\n\t\t\t\t\ttype +\n\t\t\t\t\t(t ? \", got \" + t.type : \"\") +\n\t\t\t\t\t\" at \" +\n\t\t\t\t\tpos.start.line +\n\t\t\t\t\t\":\" +\n\t\t\t\t\tpos.start.column,\n\t\t\t);\n\t\t}\n\t\treturn t;\n\t}\n\n\t/**\n\t * Looks up whether a token is enabled.\n\t * @param tokenType The token type to look up\n\t * @return {boolean} Returns whether the token is enabled\n\t */\n\tisEnabled(tokenType: T) {\n\t\treturn this._tokenTypes.isEnabled(tokenType);\n\t}\n\n\t/**\n\t * Consumes and returns the next {@link Token} in the source string.\n\t * If there are no more tokens, it returns a {@link Token} of type `$EOF`\n\t * @return {Token<T>}\n\t */\n\tnext(): Token<T> {\n\t\ttry {\n\t\t\tconst t = this.peek();\n\t\t\tthis._state.position = t.end;\n\t\t\treturn t;\n\t\t} catch (e) {\n\t\t\tthis._state.position = (e as any).end;\n\t\t\tthrow e;\n\t\t}\n\t}\n\n\t/**\n\t * Returns the next {@link Token} in the source string, but does\n\t * not consume it.\n\t * If there are no more tokens, it returns a {@link Token} of type `$EOF`\n\t * @param {number} [position=`this.position`] The position at which to start reading\n\t * @return {Token<T>}\n\t */\n\tpeek(position: number = this._state.position): Token<T> {\n\t\tconst read = (i: number = position): Token<T> | null => {\n\t\t\tif (i >= this._state.source.length) return EOF(this);\n\t\t\tconst n = this._tokenTypes.peek(this._state.source, i);\n\t\t\tif (!n || !n.result) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Unexpected input: ${this._state.source.substring(\n\t\t\t\t\t\ti,\n\t\t\t\t\t\ti + 1,\n\t\t\t\t\t)} at (${this.strpos(i).line}:${this.strpos(i).column})`,\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn n\n\t\t\t\t? n.item.skip\n\t\t\t\t\t? read(i + n.result[0].length)\n\t\t\t\t\t: new Token(\n\t\t\t\t\t\t\tn.item.type,\n\t\t\t\t\t\t\tn.result[0],\n\t\t\t\t\t\t\tn.result.map((x) => x),\n\t\t\t\t\t\t\ti,\n\t\t\t\t\t\t\ti + n.result[0].length,\n\t\t\t\t\t\t\tthis,\n\t\t\t\t\t\t)\n\t\t\t\t: null;\n\t\t};\n\t\tconst t = read();\n\t\tif (t) return t;\n\n\t\t// we did not find a match\n\t\tlet unexpected = this._state.source.substring(position, position + 1);\n\t\ttry {\n\t\t\tthis.peek(position + 1);\n\t\t} catch (e) {\n\t\t\tunexpected += (e as any).unexpected;\n\t\t}\n\t\tconst { line, column } = this.strpos(position);\n\t\tconst e = new Error(\n\t\t\t`Unexpected input: ${unexpected} at (${line}:${column})`,\n\t\t);\n\t\t(e as any).unexpected = unexpected;\n\t\t(e as any).end = position + unexpected.length;\n\t\tthrow e;\n\t}\n\n\t/**\n\t * Converts a string-index (relative to the source string) to a line and a column.\n\t * @param {number} i The index to compute\n\t * @return {Position}\n\t */\n\tstrpos(i: number): {\n\t\tline: number;\n\t\tcolumn: number;\n\t} {\n\t\tlet lines = this._state.source.substring(0, i).split(/\\r?\\n/);\n\t\tif (!Array.isArray(lines)) lines = [lines];\n\n\t\tconst line = lines.length;\n\t\tconst column = lines[lines.length - 1].length + 1;\n\t\treturn { line, column };\n\t}\n\n\t/**\n\t * Converts the token stream to an array of Tokens\n\t * @return {Token<T>[]} The array of tokens (not including (EOF))\n\t */\n\ttoArray(): Token<T>[] {\n\t\treturn [...this];\n\t}\n\n\t/**\n\t * Implements the Iterable protocol\n\t * Iterates lazily over the entire token stream (not including (EOF))\n\t * @return {Iterator<Token<T>>} Returns an iterator over all remaining tokens\n\t */\n\t*[Symbol.iterator]() {\n\t\tconst oldState = this._state.copy();\n\t\tthis._state.position = 0;\n\n\t\tlet t;\n\t\twhile (\n\t\t\t!(t = this.next()).isEof() // tslint:disable-line no-conditional-assignment\n\t\t)\n\t\t\tyield t;\n\n\t\tthis._state = oldState;\n\t}\n\n\t/**\n\t * Creates a new token type\n\t * @param {T} type The token type\n\t * @param {string|RegExp} pattern The pattern to match\n\t * @param {?boolean} skip Whether this type of token should be skipped\n\t * @return {Lexer<T>}\n\t */\n\ttoken(type: T, pattern: string | RegExp, skip?: boolean) {\n\t\tthis._tokenTypes.token(type, pattern, skip);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Creates a keyword\n\t * @param kwd The keyword to add as a token\n\t */\n\tkeyword(kwd: T) {\n\t\treturn this.token(kwd, new RegExp(`${kwd}(?=\\\\W|$)`));\n\t}\n\n\t/**\n\t * Creates an operator\n\t * @param op The operator to add as a token\n\t */\n\toperator(op: T) {\n\t\tconst sOp = new String(op).valueOf();\n\t\treturn this.token(op, sOp);\n\t}\n}\n\nexport default Lexer;\nexport { EOF, Lexer, LexerState, Token, TokenTypes };\n","// From https://github.com/jrop/pratt/blob/master/src/index.ts\n\nexport interface IPosition {\n\tline: number;\n\tcolumn: number;\n}\nexport interface ITokenPosition {\n\tstart: IPosition;\n\tend: IPosition;\n}\nexport interface IToken<T> {\n\ttype: T;\n\tmatch: string;\n\tstrpos(): ITokenPosition;\n\tisEof(): boolean;\n}\nexport interface ILexer<T> {\n\tnext(): IToken<T>;\n\tpeek(): IToken<T>;\n}\n\nexport type BPResolver = () => number;\nexport type BP = number | BPResolver;\n\nexport type StopFunction = (<T>(x: T) => T) & { isStopped(): boolean };\n\nexport type NudInfo<T> = {\n\ttoken: IToken<T>;\n\tbp: number;\n\tstop: StopFunction;\n\n\t// TODO: with the below addition of `options`\n\t// the `ctx parameter is carried through anyway\n\t// remove in a breaking API change release\n\tctx: any;\n\toptions: ParseOpts<T>;\n};\nexport type LedInfo<T> = NudInfo<T> & { left: any };\n\nexport type NudFunction<T> = (inf: NudInfo<T>) => any;\nexport type LedFunction<T> = (inf: LedInfo<T>) => any;\n\nexport type NudMap<T> = Map<T, NudFunction<T>>;\nexport type LedMap<T> = Map<T, LedFunction<T>>;\n\nexport type ParseOpts<T> = {\n\tctx?: any;\n\tstop?: StopFunction;\n\tterminals?: (number | T)[];\n};\n\nconst createStop = <T>(): StopFunction => {\n\tlet stopCalled = false;\n\treturn Object.assign(\n\t\t(x: T) => {\n\t\t\tstopCalled = true;\n\t\t\treturn x;\n\t\t},\n\t\t{\n\t\t\tisStopped() {\n\t\t\t\treturn stopCalled;\n\t\t\t},\n\t\t},\n\t) as StopFunction;\n};\n\n/**\n * A Pratt parser.\n * @example\n * const lex = new perplex.Lexer('1 + -2 * 3^4')\n * .token('NUM', /\\d+/)\n * .token('+', /\\+/)\n * .token('-', /-/)\n * .token('*', new RegExp('*'))\n * .token('/', /\\//)\n * .token('^', /\\^/)\n * .token('(', /\\(/)\n * .token(')', /\\)/)\n * .token('$SKIP_WS', /\\s+/)\n *\n * const parser = new Parser(lex)\n * .builder()\n * .nud('NUM', 100, t => parseInt(t.match))\n * .nud('-', 10, (t, bp) => -parser.parse(bp))\n * .nud('(', 10, (t, bp) => {\n * const expr = parser.parse(bp)\n * lex.expect(')')\n * return expr\n * })\n * .bp(')', 0)\n *\n * .led('^', 20, (left, t, bp) => Math.pow(left, parser.parse(20 - 1)))\n * .led('+', 30, (left, t, bp) => left + parser.parse(bp))\n * .led('-', 30, (left, t, bp) => left - parser.parse(bp))\n * .led('*', 40, (left, t, bp) => left * parser.parse(bp))\n * .led('/', 40, (left, t, bp) => left / parser.parse(bp))\n * .build()\n * parser.parse()\n * // => 161\n */\nexport class Parser<T> {\n\tpublic lexer: ILexer<T>;\n\t_nuds: NudMap<T>;\n\t_leds: LedMap<T>;\n\t_bps: Map<T, BP>;\n\n\t/**\n\t * Constructs a Parser instance\n\t * @param {ILexer<T>} lexer The lexer to obtain tokens from\n\t */\n\tconstructor(lexer: ILexer<T>) {\n\t\t/**\n\t\t * The lexer that this parser is operating on.\n\t\t * @type {ILexer<T>}\n\t\t */\n\t\tthis.lexer = lexer;\n\t\tthis._nuds = new Map();\n\t\tthis._leds = new Map();\n\t\tthis._bps = new Map();\n\t}\n\n\tprivate _type(tokenOrType: IToken<T> | T): T {\n\t\treturn tokenOrType && typeof (tokenOrType as IToken<T>).isEof == \"function\"\n\t\t\t? (tokenOrType as IToken<T>).type\n\t\t\t: (tokenOrType as T);\n\t}\n\n\t/**\n\t * Create a {@link ParserBuilder}\n\t * @return {ParserBuilder<T>} Returns the ParserBuilder\n\t */\n\tbuilder(): ParserBuilder<T> {\n\t\treturn new ParserBuilder(this);\n\t}\n\n\t/**\n\t * Define binding power for a token-type\n\t * @param {IToken<T>|T} tokenOrType The token type to define the binding power for\n\t * @returns {number} The binding power of the specified token type\n\t */\n\tbp(tokenOrType: IToken<T> | T) {\n\t\tif (tokenOrType == null) return Number.NEGATIVE_INFINITY;\n\t\tif (\n\t\t\ttokenOrType &&\n\t\t\ttypeof (tokenOrType as IToken<T>).isEof == \"function\" &&\n\t\t\t(tokenOrType as IToken<T>).isEof()\n\t\t)\n\t\t\treturn Number.NEGATIVE_INFINITY;\n\t\tconst type = this._type(tokenOrType);\n\t\tconst bp = this._bps.has(type)\n\t\t\t? this._bps.get(type)\n\t\t\t: Number.POSITIVE_INFINITY;\n\t\treturn typeof bp == \"function\" ? bp() : bp;\n\t}\n\n\t/**\n\t * Computes the token's `nud` value and returns it\n\t * @param {NudInfo<T>} info The info to compute the `nud` from\n\t * @returns {any} The result of invoking the pertinent `nud` operator\n\t */\n\tnud(info: NudInfo<T>) {\n\t\tconst fn: NudFunction<T> | undefined = this._nuds.get(info.token.type);\n\t\tif (!fn) {\n\t\t\tconst { start } = info.token.strpos();\n\t\t\tthrow new Error(\n\t\t\t\t`Unexpected token: ${info.token.match} (at ${start.line}:${start.column})`,\n\t\t\t);\n\t\t}\n\t\treturn fn(info);\n\t}\n\n\t/**\n\t * Computes a token's `led` value and returns it\n\t * @param {LedInfo<T>} info The info to compute the `led` value for\n\t * @returns {any} The result of invoking the pertinent `led` operator\n\t */\n\tled(info: LedInfo<T>) {\n\t\tlet fn = this._leds.get(info.token.type);\n\t\tif (!fn) {\n\t\t\tconst { start } = info.token.strpos();\n\t\t\tthrow new Error(\n\t\t\t\t`Unexpected token: ${info.token.match} (at ${start.line}:${start.column})`,\n\t\t\t);\n\t\t}\n\t\treturn fn(info);\n\t}\n\n\t/**\n\t * Kicks off the Pratt parser, and returns the result\n\t * @param {ParseOpts<T>} opts The parse options\n\t * @returns {any}\n\t */\n\tparse(opts: ParseOpts<T> = { terminals: [0] }): any {\n\t\tconst stop = (opts.stop = opts.stop || createStop());\n\t\tconst check = () => {\n\t\t\tif (stop.isStopped()) return false;\n\t\t\tconst t = this.lexer.peek();\n\t\t\tconst bp = this.bp(t);\n\n\t\t\t// @ts-ignore\n\t\t\treturn opts.terminals.reduce((canContinue, rbpOrType) => {\n\t\t\t\tif (!canContinue) return false;\n\t\t\t\t// @ts-ignore\n\t\t\t\tif (typeof rbpOrType == \"number\") return rbpOrType < bp;\n\t\t\t\tif (typeof rbpOrType == \"string\") return t.type != rbpOrType;\n\t\t\t}, true);\n\t\t};\n\t\tconst mkinfo = (token: IToken<T>): NudInfo<T> => {\n\t\t\tconst bp = this.bp(token);\n\t\t\t// @ts-ignore\n\t\t\treturn { token, bp, stop, ctx: opts.ctx, options: opts };\n\t\t};\n\t\tif (!opts.terminals) opts.terminals = [0];\n\t\tif (opts.terminals.length == 0) opts.terminals.push(0);\n\n\t\tlet left = this.nud(mkinfo(this.lexer.next()));\n\t\twhile (check()) {\n\t\t\tconst operator = this.lexer.next();\n\t\t\tleft = this.led(Object.assign(mkinfo(operator), { left }));\n\t\t}\n\t\treturn left;\n\t}\n}\n\n/**\n * Builds `led`/`nud` rules for a {@link Parser}\n */\nexport class ParserBuilder<T> {\n\tprivate _parser: Parser<T>;\n\n\t/**\n\t * Constructs a ParserBuilder\n\t * See also: {@link Parser.builder}\n\t * @param {Parser<T>} parser The parser\n\t */\n\tconstructor(parser: Parser<T>) {\n\t\tthis._parser = parser;\n\t}\n\n\t/**\n\t * Define `nud` for a token type\n\t * @param {T} tokenType The token type\n\t * @param {number} bp The binding power\n\t * @param {NudFunction<T>} fn The function that will parse the token\n\t * @return {ParserBuilder<T>} Returns this ParserBuilder\n\t */\n\tnud(tokenType: T, bp: BP, fn: NudFunction<T>): ParserBuilder<T> {\n\t\tthis._parser._nuds.set(tokenType, fn);\n\t\tthis.bp(tokenType, bp);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Define `led` for a token type\n\t * @param {T} tokenType The token type\n\t * @param {number} bp The binding power\n\t * @param {LedFunction<T>} fn The function that will parse the token\n\t * @return {ParserBuilder<T>} Returns this ParserBuilder\n\t */\n\tled(tokenType: T, bp: BP, fn: LedFunction<T>): ParserBuilder<T> {\n\t\tthis._parser._leds.set(tokenType, fn);\n\t\tthis.bp(tokenType, bp);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Define both `led` and `nud` for a token type at once.\n\t * The supplied `LedFunction` may be called with a null `left`\n\t * parameter when invoked from a `nud` context.\n\t * @param {strTng} tokenType The token type\n\t * @param {number} bp The binding power\n\t * @param {LedFunction<T>} fn The function that will parse the token\n\t * @return {ParserBuilder<T>} Returns this ParserBuilder\n\t */\n\teither(tokenType: T, bp: BP, fn: LedFunction<T>): ParserBuilder<T> {\n\t\treturn this.nud(tokenType, bp, (inf) =>\n\t\t\tfn(Object.assign(inf, { left: null })),\n\t\t).led(tokenType, bp, fn);\n\t}\n\n\t/**\n\t * Define the binding power for a token type\n\t * @param {T} tokenType The token type\n\t * @param {BP} bp The binding power\n\t * @return {ParserBuilder<T>} Returns this ParserBuilder\n\t */\n\tbp(tokenType: T, bp: BP): ParserBuilder<T> {\n\t\tthis._parser._bps.set(tokenType, bp);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Returns the parent {@link Parser} instance\n\t * @returns {Parser<T>}\n\t */\n\tbuild(): Parser<T> {\n\t\treturn this._parser;\n\t}\n}\n","/**\n * This module implements the commercetools product projection filter expression.\n */\n\nimport type {\n\tProductProjection,\n\tProductVariant,\n} from \"@commercetools/platform-sdk\";\nimport { nestedLookup } from \"../helpers.ts\";\nimport type { Writable } from \"../types.ts\";\nimport { Lexer, Parser } from \"./parser.ts\";\n\ntype MatchFunc = (target: any) => boolean;\n\ntype ProductProjectionFilter = (\n\tp: Writable<ProductProjection>,\n\tmarkMatchingVariants: boolean,\n) => boolean;\n\ntype TypeSymbol = {\n\ttype: \"Symbol\";\n\tkind: \"int\" | \"string\" | \"any\";\n\tvalue: any;\n};\n\ntype RangeExpressionSet = {\n\tsource: string;\n\ttype: \"RangeExpression\";\n\tchildren?: RangeExpression[];\n};\n\ntype FilterExpressionSet = {\n\tsource: string;\n\ttype: \"FilterExpression\";\n\tchildren?: FilterExpression[];\n};\n\ntype TermExpressionSet = {\n\tsource: string;\n\ttype: \"TermExpression\";\n};\n\ntype ExpressionSet =\n\t| RangeExpressionSet\n\t| FilterExpressionSet\n\t| TermExpressionSet;\n\nexport type RangeExpression = {\n\ttype: \"RangeExpression\";\n\tstart?: number;\n\tstop?: number;\n\tmatch: (obj: any) => boolean;\n};\n\nexport type FilterExpression = {\n\ttype: \"FilterExpression\";\n\tmatch: (obj: any) => boolean;\n};\n\n/**\n * Returns a function (ProductProjectionFilter).\n * NOTE: The filter can alter the resources in-place (FIXME)\n */\nexport const parseFilterExpression = (\n\tfilter: string,\n): ProductProjectionFilter => {\n\tconst exprFunc = generateMatchFunc(filter);\n\tconst [source] = filter.split(\":\", 1);\n\n\tif (source.startsWith(\"variants.\")) {\n\t\treturn filterVariants(source, exprFunc);\n\t}\n\treturn filterProduct(source, exprFunc);\n};\n\nconst getLexer = (value: string) =>\n\tnew Lexer(value)\n\t\t.token(\"MISSING\", /missing(?![-_a-z0-9]+)/i)\n\t\t.token(\"EXISTS\", /exists(?![-_a-z0-9]+)/i)\n\t\t.token(\"RANGE\", /range(?![-_a-z0-9]+)/i)\n\t\t.token(\"TO\", /to(?![-_a-z0-9]+)/i)\n\t\t.token(\"IDENTIFIER\", /[-_.a-z]+/i)\n\n\t\t.token(\"FLOAT\", /\\d+\\.\\d+/)\n\t\t.token(\"INT\", /\\d+/)\n\t\t.token(\"STRING\", /\"((?:\\\\.|[^\"\\\\])*)\"/)\n\t\t.token(\"STRING\", /'((?:\\\\.|[^'\\\\])*)'/)\n\n\t\t.token(\"COMMA\", \",\")\n\t\t.token(\"STAR\", \"*\")\n\t\t.token(\"(\", \"(\")\n\t\t.token(\":\", \":\")\n\t\t.token(\")\", \")\")\n\t\t.token('\"', '\"')\n\t\t.token(\"WS\", /\\s+/, true); // skip\n\nconst parseFilter = (filter: string): ExpressionSet => {\n\tconst lexer = getLexer(filter);\n\tconst parser = new Parser(lexer)\n\t\t.builder()\n\t\t.nud(\"IDENTIFIER\", 100, (t) => t.token.match)\n\t\t.led(\":\", 100, ({ left, bp }) => {\n\t\t\tconst parsed: any = parser.parse({ terminals: [bp - 1] });\n\t\t\tconst expressions: RangeExpression[] | FilterExpression[] | TypeSymbol[] =\n\t\t\t\t!Array.isArray(parsed) ? [parsed] : parsed;\n\n\t\t\t// Make sure we only have one type of expression (cannot mix)\n\t\t\tconst unique = new Set(expressions.map((expr) => expr.type));\n\t\t\tif (unique.size > 1) {\n\t\t\t\tthrow new Error(\"Invalid expression\");\n\t\t\t}\n\n\t\t\t// Convert plain symbols to a filter expression. For example\n\t\t\t// variants.attribute.foobar:4 where 4 is a Symbol should result\n\t\t\t// in a comparison\n\t\t\tif (expressions.some((expr) => expr.type === \"Symbol\")) {\n\t\t\t\treturn {\n\t\t\t\t\tsource: left as string,\n\t\t\t\t\ttype: \"FilterExpression\",\n\t\t\t\t\tchildren: expressions.map((e): FilterExpression => {\n\t\t\t\t\t\tif (e.type !== \"Symbol\") {\n\t\t\t\t\t\t\tthrow new Error(\"Invalid expression\");\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\ttype: \"FilterExpression\",\n\t\t\t\t\t\t\tmatch: (obj: any): boolean => obj === e.value,\n\t\t\t\t\t\t};\n\t\t\t\t\t}),\n\t\t\t\t};\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tsource: left,\n\t\t\t\ttype: expressions[0].type,\n\t\t\t\tchildren: expressions,\n\t\t\t};\n\t\t})\n\t\t.nud(\n\t\t\t\"STRING\",\n\t\t\t20,\n\t\t\t(t) =>\n\t\t\t\t({\n\t\t\t\t\ttype: \"Symbol\",\n\t\t\t\t\tkind: \"string\",\n\t\t\t\t\t// @ts-expect-error\n\t\t\t\t\tvalue: t.token.groups[1],\n\t\t\t\t}) as TypeSymbol,\n\t\t)\n\t\t.nud(\n\t\t\t\"INT\",\n\t\t\t5,\n\t\t\t(t) =>\n\t\t\t\t({\n\t\t\t\t\ttype: \"Symbol\",\n\t\t\t\t\tkind: \"int\",\n\t\t\t\t\tvalue: Number.parseInt(t.token.match, 10),\n\t\t\t\t}) as TypeSymbol,\n\t\t)\n\t\t.nud(\"STAR\", 5, (_) => ({\n\t\t\ttype: \"Symbol\",\n\t\t\tkind: \"any\",\n\t\t\tvalue: null,\n\t\t}))\n\t\t.nud(\n\t\t\t\"EXISTS\",\n\t\t\t10,\n\t\t\t({ bp }) =>\n\t\t\t\t({\n\t\t\t\t\ttype: \"FilterExpression\",\n\t\t\t\t\tmatch: (obj: any): boolean => obj !== undefined,\n\t\t\t\t}) as FilterExpression,\n\t\t)\n\t\t.nud(\n\t\t\t\"MISSING\",\n\t\t\t10,\n\t\t\t({ bp }) =>\n\t\t\t\t({\n\t\t\t\t\ttype: \"FilterExpression\",\n\t\t\t\t\tmatch: (obj: any): boolean => obj === undefined,\n\t\t\t\t}) as FilterExpression,\n\t\t)\n\t\t.led(\"COMMA\", 200, ({ left, token, bp }) => {\n\t\t\tconst expr: any = parser.parse({ terminals: [bp - 1] });\n\t\t\tif (Array.isArray(expr)) {\n\t\t\t\treturn [left, ...expr];\n\t\t\t}\n\t\t\treturn [left, expr];\n\t\t})\n\t\t.nud(\"(\", 100, (t) => {\n\t\t\tconst expr: any = parser.parse({ terminals: [\")\"] });\n\t\t\tlexer.expect(\")\");\n\t\t\treturn expr;\n\t\t})\n\t\t.bp(\")\", 0)\n\t\t.led(\"TO\", 20, ({ left, bp }) => {\n\t\t\tconst expr: any = parser.parse({ terminals: [bp - 1] });\n\t\t\treturn {\n\t\t\t\tstart: left.value,\n\t\t\t\tstop: expr.value,\n\t\t\t};\n\t\t})\n\t\t.nud(\"RANGE\", 20, ({ bp }) => {\n\t\t\tlet ranges: any = parser.parse();\n\n\t\t\t// If multiple ranges are defined we receive an array of ranges. So let's\n\t\t\t// make sure we always have an array\n\t\t\tif (!Array.isArray(ranges)) {\n\t\t\t\tranges = [ranges];\n\t\t\t}\n\n\t\t\t// Return a list of functions which matches the ranges. These functions\n\t\t\t// are processed as an OR clause\n\t\t\treturn ranges.map((range: any) => {\n\t\t\t\tlet func: (obj: any) => boolean;\n\n\t\t\t\tif (range.start !== null && range.stop !== null) {\n\t\t\t\t\tfunc = (obj: any): boolean => obj >= range.start && obj <= range.stop;\n\t\t\t\t} else if (range.start === null && range.stop !== null) {\n\t\t\t\t\tfunc = (obj: any): boolean => obj <= range.stop;\n\t\t\t\t} else if (range.start !== null && range.stop === null) {\n\t\t\t\t\tfunc = (obj: any): boolean => obj >= range.start;\n\t\t\t\t} else {\n\t\t\t\t\tfunc = (obj: any): boolean => true;\n\t\t\t\t}\n\n\t\t\t\treturn {\n\t\t\t\t\ttype: \"RangeExpression\",\n\t\t\t\t\tstart: range.start,\n\t\t\t\t\tstop: range.stop,\n\t\t\t\t\tmatch: func,\n\t\t\t\t} as RangeExpression;\n\t\t\t});\n\t\t})\n\t\t.build();\n\n\treturn parser.parse();\n};\n\nconst generateMatchFunc = (filter: string) => {\n\tconst result = parseFilter(filter);\n\tif (!result) {\n\t\t// const lines = filter.split('\\n')\n\t\t// const column = lines[lines.length - 1].length\n\t\tthrow new Error(`Syntax error while parsing '${filter}'.`);\n\t}\n\tif (result.type === \"TermExpression\") {\n\t\tthrow new Error(`Syntax error while parsing '${filter}'.`);\n\t}\n\n\treturn (obj: any) => {\n\t\tif (!result.children) return false;\n\t\treturn result.children.some((c) => c.match(obj));\n\t};\n};\n\nexport const generateFacetFunc = (filter: string): ExpressionSet => {\n\tif (!filter.includes(\":\")) {\n\t\treturn {\n\t\t\tsource: filter,\n\t\t\ttype: \"TermExpression\",\n\t\t};\n\t}\n\treturn parseFilter(filter);\n};\n\nconst filterProduct =\n\t(source: string, exprFunc: MatchFunc): ProductProjectionFilter =>\n\t(p: ProductProjection, markMatchingVariants: boolean): boolean => {\n\t\tconst value = nestedLookup(p, source);\n\t\treturn exprFunc(value);\n\t};\n\nconst filterVariants =\n\t(source: string, exprFunc: MatchFunc): ProductProjectionFilter =>\n\t(p: ProductProjection, markMatchingVariants: boolean): boolean => {\n\t\tconst [, ...paths] = source.split(\".\");\n\t\tconst path = paths.join(\".\");\n\n\t\tconst variants = getVariants(p) as Writable<ProductVariant>[];\n\t\tfor (const variant of variants) {\n\t\t\tconst value = resolveVariantValue(variant, path);\n\n\t\t\tif (exprFunc(value)) {\n\t\t\t\t// If markMatchingVariants parameter is true those ProductVariants that\n\t\t\t\t// match the search query have the additional field isMatchingVariant\n\t\t\t\t// set to true. For the other variants in the same product projection\n\t\t\t\t// this field is set to false.\n\t\t\t\tif (markMatchingVariants) {\n\t\t\t\t\tfor (const v of variants) {\n\t\t\t\t\t\tv.isMatchingVariant = false;\n\t\t\t\t\t}\n\t\t\t\t\tvariant.isMatchingVariant = true;\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\treturn false;\n\t};\n\nexport const resolveVariantValue = (obj: ProductVariant, path: string): any => {\n\tif (path === undefined) {\n\t\treturn obj;\n\t}\n\tif (path.startsWith(\"variants.\")) {\n\t\tpath = path.substring(path.indexOf(\".\") + 1);\n\t}\n\n\tif (path.startsWith(\"attributes.\")) {\n\t\tconst [, attrName, ...rest] = path.split(\".\");\n\t\tif (!obj.attributes) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tfor (const attr of obj.attributes) {\n\t\t\tif (attr.name === attrName) {\n\t\t\t\treturn nestedLookup(attr.value, rest.join(\".\"));\n\t\t\t}\n\t\t}\n\t}\n\n\tif (path === \"price.centAmount\") {\n\t\treturn obj.prices && obj.prices.length > 0\n\t\t\t? obj.prices[0].value.centAmount\n\t\t\t: undefined;\n\t}\n\n\treturn nestedLookup(obj, path);\n};\n\nexport const getVariants = (p: ProductProjection): ProductVariant[] => [\n\tp.masterVariant,\n\t...(p.variants ?? []),\n];\n","import type {\n\t_SearchQuery,\n\t_SearchQueryExpression,\n\t_SearchQueryExpressionValue,\n\tProductProjection,\n\tProductVariant,\n\tSearchAndExpression,\n\tSearchDateRangeExpression,\n\tSearchDateTimeRangeExpression,\n\tSearchExactExpression,\n\tSearchExistsExpression,\n\tSearchFilterExpression,\n\tSearchFullTextExpression,\n\tSearchFullTextPrefixExpression,\n\tSearchLongRangeExpression,\n\tSearchNotExpression,\n\tSearchNumberRangeExpression,\n\tSearchOrExpression,\n\tSearchPrefixExpression,\n\tSearchTimeRangeExpression,\n\tSearchWildCardExpression,\n} from \"@commercetools/platform-sdk\";\nimport { nestedLookup } from \"#src/helpers.ts\";\nimport type { Writable } from \"../types.ts\";\nimport { getVariants } from \"./projectionSearchFilter.ts\";\n\ntype ProductSearchFilterFunc = (\n\tp: Writable<ProductProjection>,\n\tmarkMatchingVariants: boolean,\n) => boolean;\n\n// @TODO: Implement field boosting:\n// https://docs.commercetools.com/merchant-center/advanced-product-search#boost-field\nexport const parseSearchQuery = (\n\tsearchQuery: _SearchQuery,\n): ProductSearchFilterFunc => {\n\tif (isSearchAndExpression(searchQuery)) {\n\t\treturn (obj, markMatchingVariant) =>\n\t\t\tsearchQuery.and.every((expr) => {\n\t\t\t\tconst filterFunc = parseSearchQuery(expr);\n\n\t\t\t\treturn filterFunc(obj, markMatchingVariant);\n\t\t\t});\n\t}\n\n\tif (isSearchOrExpression(searchQuery)) {\n\t\treturn (obj, markMatchingVariant) =>\n\t\t\tsearchQuery.or.some((expr) => {\n\t\t\t\tconst filterFunc = parseSearchQuery(expr);\n\n\t\t\t\treturn filterFunc(obj, markMatchingVariant);\n\t\t\t});\n\t}\n\n\tif (isSearchNotExpression(searchQuery)) {\n\t\treturn (obj, markMatchingVariant) =>\n\t\t\t!parseSearchQuery(searchQuery.not)(obj, markMatchingVariant);\n\t}\n\n\tif (isSearchFilterExpression(searchQuery)) {\n\t\t// Matching resources of a query are checked for their relevancy to the search.\n\t\t// The relevancy is expressed by an internal score.\n\t\t// All expressions except filter expressions contribute to that score.\n\t\t// All sub-expressions of a filter are implicitly connected with an and expression.\n\t\t// NOTE: for now just implementing it like a AND expression\n\t\treturn (obj, markMatchingVariant) =>\n\t\t\tsearchQuery.filter.every((expr) => {\n\t\t\t\tconst filterFunc = parseSearchQuery(expr);\n\n\t\t\t\treturn filterFunc(obj, markMatchingVariant);\n\t\t\t});\n\t}\n\n\tif (isSearchRangeExpression(searchQuery)) {\n\t\tconst generateRangeMatchFunc = (value: any) => {\n\t\t\tconst rangeFilters = [];\n\n\t\t\tif (searchQuery.range.gte) {\n\t\t\t\trangeFilters.push(value >= searchQuery.range.gte);\n\t\t\t}\n\n\t\t\tif (searchQuery.range.gt) {\n\t\t\t\trangeFilters.push(value > searchQuery.range.gt);\n\t\t\t}\n\n\t\t\tif (searchQuery.range.lte) {\n\t\t\t\trangeFilters.push(value <= searchQuery.range.lte);\n\t\t\t}\n\n\t\t\tif (searchQuery.range.lt) {\n\t\t\t\trangeFilters.push(value < searchQuery.range.lt);\n\t\t\t}\n\n\t\t\treturn rangeFilters.every((filter) => filter);\n\t\t};\n\n\t\treturn generateFieldMatchFunc(generateRangeMatchFunc, searchQuery.range);\n\t}\n\n\tif (isSearchExactExpression(searchQuery)) {\n\t\tif (Array.isArray(searchQuery.exact.values)) {\n\t\t\treturn generateFieldMatchFunc(\n\t\t\t\t(value: any) => (searchQuery.exact.values ?? []).includes(value),\n\t\t\t\tsearchQuery.exact,\n\t\t\t);\n\t\t}\n\n\t\treturn generateFieldMatchFunc(\n\t\t\t(value: any) => value === searchQuery.exact.value,\n\t\t\tsearchQuery.exact,\n\t\t);\n\t}\n\n\tif (isSearchExistsExpression(searchQuery)) {\n\t\treturn generateFieldMatchFunc((value: any) => !!value, searchQuery.exists);\n\t}\n\n\tif (isSearchFullTextExpression(searchQuery)) {\n\t\t// @TODO: Implement fulltext search, to fully support functionality offered by commercetools:\n\t\t// https://docs.commercetools.com/api/search-query-language#fulltext\n\t\treturn generateFieldMatchFunc(\n\t\t\t(value: any) => value.includes(searchQuery.fullText.value),\n\t\t\tsearchQuery.fullText,\n\t\t);\n\t}\n\n\tif (isSearchFullTextPrefixExpression(searchQuery)) {\n\t\t// @TODO: Implement fulltext search, to fully support functionality offered by commercetools:\n\t\t// https://docs.commercetools.com/api/search-query-language#fulltext\n\t\treturn generateFieldMatchFunc(\n\t\t\t(value: any) => value.startsWith(searchQuery.fullTextPrefix.value),\n\t\t\tsearchQuery.fullTextPrefix,\n\t\t);\n\t}\n\n\tif (isSearchPrefixExpression(searchQuery)) {\n\t\treturn generateFieldMatchFunc(\n\t\t\t(value: any) => value.startsWith(searchQuery.prefix.value),\n\t\t\tsearchQuery.prefix,\n\t\t);\n\t}\n\n\tif (isSearchWildCardExpression(searchQuery)) {\n\t\t// @TODO: Fully implement wildcard search, as specified:\n\t\t// https://docs.commercetools.com/api/search-query-language#fulltext\n\t\tconst generateWildcardMatchFunc = (value: any) => {\n\t\t\tconst wildCardValues = searchQuery.wildcard.value\n\t\t\t\t.split(\"*\")\n\t\t\t\t.filter((v: string) => !!v);\n\n\t\t\tif (searchQuery.wildcard.caseInsensitive) {\n\t\t\t\treturn wildCardValues.every((wildCardValue: string) =>\n\t\t\t\t\tvalue.toLowerCase().includes(wildCardValue.toLowerCase()),\n\t\t\t\t);\n\t\t\t}\n\n\t\t\treturn wildCardValues.every((wildCardValue: string) =>\n\t\t\t\tvalue.includes(wildCardValue),\n\t\t\t);\n\t\t};\n\n\t\treturn generateFieldMatchFunc(\n\t\t\tgenerateWildcardMatchFunc,\n\t\t\tsearchQuery.wildcard,\n\t\t);\n\t}\n\n\tthrow new Error(\"Unsupported search query expression\");\n};\n\nconst generateFieldMatchFunc = (\n\tmatchFunc: (value: any) => boolean,\n\tsearchQuery: _SearchQueryExpressionValue,\n) => {\n\tconst generateMatchFunc = (\n\t\tobj: ProductProjection,\n\t\tmarkMatchingVariants: boolean,\n\t) => {\n\t\tif (searchQuery.field.startsWith(\"variants.\")) {\n\t\t\tconst variantField = searchQuery.field.substring(\n\t\t\t\tsearchQuery.field.indexOf(\".\") + 1,\n\t\t\t);\n\n\t\t\tconst variants = getVariants(obj) as Writable<ProductVariant>[];\n\t\t\tfor (const variant of variants) {\n\t\t\t\tconst value = resolveFieldValue(variant, {\n\t\t\t\t\t...searchQuery,\n\t\t\t\t\tfield: variantField,\n\t\t\t\t});\n\n\t\t\t\tif (matchFunc(value)) {\n\t\t\t\t\tif (markMatchingVariants) {\n\t\t\t\t\t\tfor (const v of variants) {\n\t\t\t\t\t\t\tv.isMatchingVariant = false;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tvariant.isMatchingVariant = true;\n\t\t\t\t\t}\n\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn false;\n\t\t}\n\n\t\treturn matchFunc(resolveFieldValue(obj, searchQuery));\n\t};\n\n\treturn generateMatchFunc;\n};\n\nconst resolveFieldValue = (\n\tobj: any,\n\tsearchQuery: _SearchQueryExpressionValue,\n) => {\n\tif (searchQuery.field === undefined) {\n\t\tthrow new Error(\"Missing field path in query expression\");\n\t}\n\n\tlet fieldPath = searchQuery.field;\n\tconst language = \"language\" in searchQuery ? searchQuery.language : undefined;\n\n\tif (fieldPath.startsWith(\"variants.\")) {\n\t\tfieldPath = fieldPath.substring(fieldPath.indexOf(\".\") + 1);\n\t}\n\n\tif (fieldPath.startsWith(\"attributes.\")) {\n\t\tconst [, attrName, ...rest] = fieldPath.split(\".\");\n\t\tif (!obj.attributes) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tfor (const attr of obj.attributes) {\n\t\t\tif (attr.name === attrName) {\n\t\t\t\treturn nestedLookupByLanguage(attr.value, rest.join(\".\"), language);\n\t\t\t}\n\t\t}\n\t}\n\n\tif (fieldPath === \"prices.currentCentAmount\") {\n\t\treturn obj.prices && obj.prices.length > 0\n\t\t\t? obj.prices[0].value.centAmount\n\t\t\t: undefined;\n\t}\n\n\treturn nestedLookupByLanguage(obj, fieldPath, language);\n};\n\nconst nestedLookupByLanguage = (\n\tobj: any,\n\tpath: string,\n\tlanguage?: string,\n): any => {\n\tconst value = nestedLookup(obj, path);\n\n\tif (language && value && typeof value === \"object\") {\n\t\t// Due to Commercetools supporting \"en\", but also \"en-US\" as language, we need to find the best match\n\t\tconst matchingLanguageKey = Object.keys(value).find((key) =>\n\t\t\tkey.toLowerCase().startsWith(language.toLowerCase()),\n\t\t);\n\n\t\treturn matchingLanguageKey ? value[matchingLanguageKey] : undefined;\n\t}\n\n\treturn value;\n};\n\n// type guards\nconst isSearchAndExpression = (\n\texpr: _SearchQuery,\n): expr is SearchAndExpression =>\n\t(expr as SearchAndExpression).and !== undefined;\n\nconst isSearchOrExpression = (expr: _SearchQuery): expr is SearchOrExpression =>\n\t(expr as SearchOrExpression).or !== undefined;\n\ntype SearchRangeExpression =\n\t| SearchDateRangeExpression\n\t| SearchDateTimeRangeExpression\n\t| SearchLongRangeExpression\n\t| SearchNumberRangeExpression\n\t| SearchTimeRangeExpression;\n\n// Type guard for SearchNotExpression\nconst isSearchNotExpression = (\n\texpr: _SearchQueryExpression,\n): expr is SearchNotExpression =>\n\t(expr as SearchNotExpression).not !== undefined;\n\n// Type guard for SearchFilterExpression\nconst isSearchFilterExpression = (\n\texpr: _SearchQueryExpression,\n): expr is SearchFilterExpression =>\n\t(expr as SearchFilterExpression).filter !== undefined;\n\n// Type guard for SearchDateRangeExpression\nconst isSearchRangeExpression = (\n\texpr: _SearchQueryExpression,\n): expr is SearchRangeExpression =>\n\t(expr as SearchRangeExpression).range !== undefined;\n\n// Type guard for SearchExactExpression\nconst isSearchExactExpression = (\n\texpr: _SearchQueryExpression,\n): expr is SearchExactExpression =>\n\t(expr as SearchExactExpression).exact !== undefined;\n\n// Type guard for SearchExistsExpression\nconst isSearchExistsExpression = (\n\texpr: _SearchQueryExpression,\n): expr is SearchExistsExpression =>\n\t(expr as SearchExistsExpression).exists !== undefined;\n\n// Type guard for SearchFullTextExpression\nconst isSearchFullTextExpression = (\n\texpr: _SearchQueryExpression,\n): expr is SearchFullTextExpression =>\n\t(expr as SearchFullTextExpression).fullText !== undefined;\n\n// Type guard for SearchFullTextPrefixExpression\nconst isSearchFullTextPrefixExpression = (\n\texpr: _SearchQueryExpression,\n): expr is SearchFullTextPrefixExpression =>\n\t(expr as SearchFullTextPrefixExpression).fullTextPrefix !== undefined;\n\n// Type guard for SearchPrefixExpression\nconst isSearchPrefixExpression = (\n\texpr: _SearchQueryExpression,\n): expr is SearchPrefixExpression =>\n\t(expr as SearchPrefixExpression).prefix !== undefined;\n\n// Type guard for SearchWildCardExpression\nconst isSearchWildCardExpression = (\n\texpr: _SearchQueryExpression,\n): expr is SearchWildCardExpression =>\n\t(expr as SearchWildCardExpression).wildcard !== undefined;\n","import type {\n\t_SearchQuery,\n\t_SearchQueryExpression,\n\tSearchAndExpression,\n\tSearchAnyValue,\n\tSearchDateRangeExpression,\n\tSearchDateTimeRangeExpression,\n\tSearchExactExpression,\n\tSearchExistsExpression,\n\tSearchFilterExpression,\n\tSearchFullTextExpression,\n\tSearchFullTextPrefixExpression,\n\tSearchLongRangeExpression,\n\tSearchNotExpression,\n\tSearchNumberRangeExpression,\n\tSearchOrExpression,\n\tSearchPrefixExpression,\n\tSearchTimeRangeExpression,\n\tSearchWildCardExpression,\n} from \"@commercetools/platform-sdk\";\n\nexport const validateSearchQuery = (query: _SearchQuery): void => {\n\tif (isSearchAndExpression(query)) {\n\t\tfor (const expr of query.and) {\n\t\t\tvalidateSearchQuery(expr);\n\t\t}\n\t} else if (isSearchOrExpression(query)) {\n\t\tfor (const expr of query.or) {\n\t\t\tvalidateSearchQuery(expr);\n\t\t}\n\t} else if (isSearchNotExpression(query)) {\n\t\tvalidateSearchQuery(query.not);\n\t} else if (\n\t\tisSearchFilterExpression(query) ||\n\t\tisSearchRangeExpression(query) ||\n\t\tisSearchExactExpression(query) ||\n\t\tisSearchExistsExpression(query) ||\n\t\tisSearchFullTextExpression(query) ||\n\t\tisSearchFullTextPrefixExpression(query) ||\n\t\tisSearchPrefixExpression(query) ||\n\t\tisSearchWildCardExpression(query) ||\n\t\tisSearchAnyValue(query)\n\t) {\n\t\treturn;\n\t} else {\n\t\tthrow new Error(\"Unsupported search query expression\");\n\t}\n};\n\n// Type guards\nexport const isSearchAndExpression = (\n\texpr: _SearchQuery,\n): expr is SearchAndExpression =>\n\t(expr as SearchAndExpression).and !== undefined;\n\nexport const isSearchOrExpression = (\n\texpr: _SearchQuery,\n): expr is SearchOrExpression => (expr as SearchOrExpression).or !== undefined;\n\nexport type SearchRangeExpression =\n\t| SearchDateRangeExpression\n\t| SearchDateTimeRangeExpression\n\t| SearchLongRangeExpression\n\t| SearchNumberRangeExpression\n\t| SearchTimeRangeExpression;\n\n// Type guard for SearchNotExpression\nexport const isSearchNotExpression = (\n\texpr: _SearchQueryExpression,\n): expr is SearchNotExpression =>\n\t(expr as SearchNotExpression).not !== undefined;\n\n// Type guard for SearchFilterExpression\nexport const isSearchFilterExpression = (\n\texpr: _SearchQueryExpression,\n): expr is SearchFilterExpression =>\n\t(expr as SearchFilterExpression).filter !== undefined;\n\n// Type guard for SearchDateRangeExpression\nexport const isSearchRangeExpression = (\n\texpr: _SearchQueryExpression,\n): expr is SearchRangeExpression =>\n\t(expr as SearchRangeExpression).range !== undefined;\n\n// Type guard for SearchExactExpression\nexport const isSearchExactExpression = (\n\texpr: _SearchQueryExpression,\n): expr is SearchExactExpression =>\n\t(expr as SearchExactExpression).exact !== undefined;\n\n// Type guard for SearchExistsExpression\nexport const isSearchExistsExpression = (\n\texpr: _SearchQueryExpression,\n): expr is SearchExistsExpression =>\n\t(expr as SearchExistsExpression).exists !== undefined;\n\n// Type guard for SearchFullTextExpression\nexport const isSearchFullTextExpression = (\n\texpr: _SearchQueryExpression,\n): expr is SearchFullTextExpression =>\n\t(expr as SearchFullTextExpression).fullText !== undefined;\n\n// Type guard for SearchFullTextPrefixExpression\nexport const isSearchFullTextPrefixExpression = (\n\texpr: _SearchQueryExpression,\n): expr is SearchFullTextPrefixExpression =>\n\t(expr as SearchFullTextPrefixExpression).fullTextPrefix !== undefined;\n\n// Type guard for SearchPrefixExpression\nexport const isSearchPrefixExpression = (\n\texpr: _SearchQueryExpression,\n): expr is SearchPrefixExpression =>\n\t(expr as SearchPrefixExpression).prefix !== undefined;\n\n// Type guard for SearchWildCardExpression\nexport const isSearchWildCardExpression = (\n\texpr: _SearchQueryExpression,\n): expr is SearchWildCardExpression =>\n\t(expr as SearchWildCardExpression).wildcard !== undefined;\n\n// Type guard for SearchAnyValue\nexport const isSearchAnyValue = (\n\texpr: _SearchQueryExpression,\n): expr is SearchAnyValue => (expr as SearchAnyValue).value !== undefined;\n","import type {\n\tInvalidInputError,\n\tPrice,\n\tProductProjection,\n\tProductVariant,\n} from \"@commercetools/platform-sdk\";\nimport { CommercetoolsError } from \"./exceptions.ts\";\nimport type { Writable } from \"./types.ts\";\n\nexport type PriceSelector = {\n\tcurrency?: string;\n\tcountry?: string;\n\tcustomerGroup?: string;\n\tchannel?: string;\n};\n\n/**\n * Apply the price selector on all the variants. The price selector is applied\n * on all the prices per variant and the first match per variant is stored in\n * the scopedPrice attribute\n */\nexport const applyPriceSelector = (\n\tproducts: ProductProjection[],\n\tselector: PriceSelector,\n\tnoScopedPrice = false,\n) => {\n\tvalidatePriceSelector(selector);\n\n\tfor (const product of products) {\n\t\t// Get list of all variants (master + variants)\n\t\tconst variants: Writable<ProductVariant>[] = [\n\t\t\tproduct.masterVariant,\n\t\t\t...(product.variants ?? []),\n\t\t].filter((x) => x !== undefined);\n\n\t\tfor (const variant of variants) {\n\t\t\tconst scopedPrices =\n\t\t\t\tvariant.prices?.filter((p) => priceSelectorFilter(p, selector)) ?? [];\n\n\t\t\tif (scopedPrices.length > 0) {\n\t\t\t\tconst price = scopedPrices[0];\n\n\t\t\t\tvariant.price = scopedPrices[0];\n\t\t\t\tif (!noScopedPrice) {\n\t\t\t\t\tvariant.scopedPriceDiscounted = false;\n\t\t\t\t\tvariant.scopedPrice = {\n\t\t\t\t\t\t...price,\n\t\t\t\t\t\tcurrentValue: price.value,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n};\n\nconst validatePriceSelector = (selector: PriceSelector) => {\n\tif (\n\t\t(selector.country || selector.channel || selector.customerGroup) &&\n\t\t!selector.currency\n\t) {\n\t\tthrow new CommercetoolsError<InvalidInputError>(\n\t\t\t{\n\t\t\t\tcode: \"InvalidInput\",\n\t\t\t\tmessage:\n\t\t\t\t\t\"The price selecting parameters country, channel and customerGroup \" +\n\t\t\t\t\t\"cannot be used without the currency.\",\n\t\t\t},\n\t\t\t400,\n\t\t);\n\t}\n};\n\n/**\n * Return a boolean to indicate if the price matches the selector. Price\n * selection requires that if the selector or the price has a specific value\n * then it should match.\n */\nexport const priceSelectorFilter = (\n\tprice: Price,\n\tselector: PriceSelector,\n): boolean => {\n\tif (\n\t\t(selector.country || price.country) &&\n\t\tselector.country !== price.country\n\t) {\n\t\treturn false;\n\t}\n\n\tif (\n\t\t(selector.currency || price.value.currencyCode) &&\n\t\tselector.currency !== price.value.currencyCode\n\t) {\n\t\treturn false;\n\t}\n\n\tif (\n\t\t(selector.channel || price.channel?.id) &&\n\t\tselector.channel !== price.channel?.id\n\t) {\n\t\treturn false;\n\t}\n\n\tif (\n\t\t(selector.customerGroup || price.customerGroup?.id) &&\n\t\tselector.customerGroup !== price.customerGroup?.id\n\t) {\n\t\treturn false;\n\t}\n\n\treturn true;\n};\n","import type {\n\tInvalidInputError,\n\tProduct,\n\tProductPagedSearchResponse,\n\tProductProjection,\n\tProductSearchRequest,\n\tProductSearchResult,\n} from \"@commercetools/platform-sdk\";\nimport type { Config } from \"./config.ts\";\nimport { CommercetoolsError } from \"./exceptions.ts\";\nimport { parseSearchQuery } from \"./lib/productSearchFilter.ts\";\nimport { validateSearchQuery } from \"./lib/searchQueryTypeChecker.ts\";\nimport { applyPriceSelector } from \"./priceSelector.ts\";\nimport type { AbstractStorage } from \"./storage/index.ts\";\n\ninterface ProductSearchVariantAvailability {\n\tisOnStock: boolean;\n\tavailableQuantity: number;\n\tisOnStockForChannel: string | undefined;\n}\n\nexport class ProductSearch {\n\tprotected _storage: AbstractStorage;\n\n\tconstructor(config: Config) {\n\t\tthis._storage = config.storage;\n\t}\n\n\tsearch(\n\t\tprojectKey: string,\n\t\tparams: ProductSearchRequest,\n\t): ProductPagedSearchResponse {\n\t\tconst availabilityBySku = this._storage\n\t\t\t.all(projectKey, \"inventory-entry\")\n\t\t\t.reduce((acc, entry) => {\n\t\t\t\tconst existingEntry = acc.get(entry.sku);\n\n\t\t\t\tacc.set(entry.sku, {\n\t\t\t\t\tisOnStock: existingEntry?.isOnStock || entry.quantityOnStock > 0,\n\t\t\t\t\tavailableQuantity:\n\t\t\t\t\t\texistingEntry?.availableQuantity ?? 0 + entry.quantityOnStock,\n\t\t\t\t\t// NOTE: This doesn't handle inventory entries for multiple channels,\n\t\t\t\t\t// so it doesn't exactly replicate the behavior of the commercetools api.\n\t\t\t\t\tisOnStockForChannel:\n\t\t\t\t\t\texistingEntry?.isOnStockForChannel ?? entry.supplyChannel?.id,\n\t\t\t\t});\n\n\t\t\t\treturn acc;\n\t\t\t}, new Map<string, ProductSearchVariantAvailability>());\n\n\t\tlet productResources = this._storage\n\t\t\t.all(projectKey, \"product\")\n\t\t\t.map((r) =>\n\t\t\t\tthis.transformProduct(\n\t\t\t\t\tr,\n\t\t\t\t\tparams.productProjectionParameters?.staged ?? false,\n\t\t\t\t\tavailabilityBySku,\n\t\t\t\t),\n\t\t\t)\n\t\t\t.filter((p) => {\n\t\t\t\tif (!(params.productProjectionParameters?.staged ?? false)) {\n\t\t\t\t\treturn p.published;\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t});\n\n\t\tconst markMatchingVariant = params.markMatchingVariants ?? false;\n\n\t\t// Apply filters pre facetting\n\t\tif (params.query) {\n\t\t\ttry {\n\t\t\t\tvalidateSearchQuery(params.query);\n\n\t\t\t\tconst matchFunc = parseSearchQuery(params.query);\n\n\t\t\t\t// Filters can modify the output. So clone the resources first.\n\t\t\t\tproductResources = productResources.filter((resource) =>\n\t\t\t\t\tmatchFunc(resource, markMatchingVariant),\n\t\t\t\t);\n\t\t\t} catch (err) {\n\t\t\t\tthrow new CommercetoolsError<InvalidInputError>(\n\t\t\t\t\t{\n\t\t\t\t\t\tcode: \"InvalidInput\",\n\t\t\t\t\t\tmessage: (err as any).message,\n\t\t\t\t\t},\n\t\t\t\t\t400,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\t// Apply the priceSelector\n\t\tif (params.productProjectionParameters) {\n\t\t\tapplyPriceSelector(productResources, {\n\t\t\t\tcountry: params.productProjectionParameters.priceCountry,\n\t\t\t\tchannel: params.productProjectionParameters.priceChannel,\n\t\t\t\tcustomerGroup: params.productProjectionParameters.priceCustomerGroup,\n\t\t\t\tcurrency: params.productProjectionParameters.priceCurrency,\n\t\t\t});\n\t\t}\n\n\t\t// @TODO: Determine whether or not to spoof search, facet filtering, wildcard, boosting and/or sorting.\n\t\t// For now this is deliberately not supported.\n\n\t\tconst offset = params.offset || 0;\n\t\tconst limit = params.limit || 20;\n\t\tconst productProjectionsResult = productResources.slice(\n\t\t\toffset,\n\t\t\toffset + limit,\n\t\t);\n\n\t\t/**\n\t\t * Do not supply productProjection if productProjectionParameters are not given\n\t\t * https://docs.commercetools.com/api/projects/product-search#with-product-projection-parameters\n\t\t */\n\t\tconst productProjectionsParameterGiven =\n\t\t\t!!params?.productProjectionParameters;\n\n\t\t// Transform to ProductSearchResult\n\t\tconst results: ProductSearchResult[] = productProjectionsResult.map(\n\t\t\t(product) => ({\n\t\t\t\tproductProjection: productProjectionsParameterGiven\n\t\t\t\t\t? product\n\t\t\t\t\t: undefined,\n\t\t\t\tid: product.id,\n\t\t\t\t/**\n\t\t\t\t * @TODO: possibly add support for optional matchingVariants\n\t\t\t\t * \t\thttps://docs.commercetools.com/api/projects/product-search#productsearchmatchingvariants\n\t\t\t\t */\n\t\t\t}),\n\t\t);\n\n\t\treturn {\n\t\t\ttotal: productResources.length,\n\t\t\toffset: offset,\n\t\t\tlimit: limit,\n\t\t\tresults: results,\n\t\t\tfacets: [],\n\t\t};\n\t}\n\n\ttransformProduct(\n\t\tproduct: Product,\n\t\tstaged: boolean,\n\t\tavailabilityBySku: Map<string, ProductSearchVariantAvailability>,\n\t): ProductProjection {\n\t\tconst obj = !staged\n\t\t\t? product.masterData.current\n\t\t\t: product.masterData.staged;\n\n\t\tconst getVariantAvailability = (sku?: string) => {\n\t\t\tif (!sku) {\n\t\t\t\treturn {\n\t\t\t\t\tisOnStock: false,\n\t\t\t\t\tavailableQuantity: 0,\n\t\t\t\t\tisOnStockForChannel: undefined,\n\t\t\t\t};\n\t\t\t}\n\t\t\treturn (\n\t\t\t\tavailabilityBySku.get(sku) || {\n\t\t\t\t\tisOnStock: false,\n\t\t\t\t\tavailableQuantity: 0,\n\t\t\t\t\tisOnStockForChannel: undefined,\n\t\t\t\t}\n\t\t\t);\n\t\t};\n\n\t\treturn {\n\t\t\tid: product.id,\n\t\t\tcreatedAt: product.createdAt,\n\t\t\tlastModifiedAt: product.lastModifiedAt,\n\t\t\tversion: product.version,\n\t\t\tname: obj.name,\n\t\t\tkey: product.key,\n\t\t\tdescription: obj.description,\n\t\t\tmetaDescription: obj.metaDescription,\n\t\t\tslug: obj.slug,\n\t\t\tcategories: obj.categories,\n\t\t\tattributes: obj.attributes,\n\t\t\tmasterVariant: {\n\t\t\t\t...obj.masterVariant,\n\t\t\t\tavailability: getVariantAvailability(obj.masterVariant.sku),\n\t\t\t},\n\t\t\tvariants: obj.variants.map((variant) => ({\n\t\t\t\t...variant,\n\t\t\t\tavailability: getVariantAvailability(variant.sku),\n\t\t\t})),\n\t\t\tproductType: product.productType,\n\t\t\thasStagedChanges: product.masterData.hasStagedChanges,\n\t\t\tpublished: product.masterData.published,\n\t\t};\n\t}\n}\n","import { isDeepStrictEqual } from \"node:util\";\nimport type {\n\tAsset,\n\tAssetDraft,\n\tChannelReference,\n\tPrice,\n\tPriceDraft,\n\tProduct,\n\tProductData,\n\tProductVariant,\n\tProductVariantDraft,\n} from \"@commercetools/platform-sdk\";\nimport { v4 as uuidv4 } from \"uuid\";\nimport type { AbstractStorage } from \"#src/storage/index.ts\";\nimport type { Writable } from \"#src/types.ts\";\nimport type { RepositoryContext } from \"../abstract.ts\";\nimport {\n\tcreateCustomFields,\n\tcreateTypedMoney,\n\tgetReferenceFromResourceIdentifier,\n} from \"../helpers.ts\";\n\ninterface VariantResult {\n\tvariant: Writable<ProductVariant> | undefined;\n\tisMasterVariant: boolean;\n\tvariantIndex: number;\n}\n\nexport const getVariant = (\n\tproductData: ProductData,\n\tvariantId?: number,\n\tsku?: string,\n): VariantResult => {\n\tconst variants = [productData.masterVariant, ...productData.variants];\n\tconst foundVariant = variants.find((variant: ProductVariant) => {\n\t\tif (variantId) {\n\t\t\treturn variant.id === variantId;\n\t\t}\n\t\tif (sku) {\n\t\t\treturn variant.sku === sku;\n\t\t}\n\t\treturn false;\n\t});\n\n\tconst isMasterVariant = foundVariant === productData.masterVariant;\n\treturn {\n\t\tvariant: foundVariant,\n\t\tisMasterVariant,\n\t\tvariantIndex:\n\t\t\t!isMasterVariant && foundVariant\n\t\t\t\t? productData.variants.indexOf(foundVariant)\n\t\t\t\t: -1,\n\t};\n};\n\n// Check if the product still has staged data that is different from the\n// current data.\nexport const checkForStagedChanges = (product: Writable<Product>) => {\n\tif (!product.masterData.staged) {\n\t\tproduct.masterData.staged = product.masterData.current;\n\t}\n\n\tif (\n\t\tisDeepStrictEqual(product.masterData.current, product.masterData.staged)\n\t) {\n\t\tproduct.masterData.hasStagedChanges = false;\n\t} else {\n\t\tproduct.masterData.hasStagedChanges = true;\n\t}\n};\n\nexport const variantFromDraft = (\n\tcontext: RepositoryContext,\n\tstorage: AbstractStorage,\n\tvariantId: number,\n\tvariant: ProductVariantDraft,\n): ProductVariant => ({\n\tid: variantId,\n\tsku: variant?.sku,\n\tkey: variant?.key,\n\tattributes: variant?.attributes ?? [],\n\tprices: variant?.prices?.map((p) => priceFromDraft(context, storage, p)),\n\tassets: variant.assets?.map((a) => assetFromDraft(context, storage, a)) ?? [],\n\timages: variant.images ?? [],\n});\n\nexport const assetFromDraft = (\n\tcontext: RepositoryContext,\n\tstorage: AbstractStorage,\n\tdraft: AssetDraft,\n): Asset => {\n\tconst asset: Asset = {\n\t\t...draft,\n\t\tid: uuidv4(),\n\t\tcustom: createCustomFields(draft.custom, context.projectKey, storage),\n\t};\n\treturn asset;\n};\n\nexport const priceFromDraft = (\n\tcontext: RepositoryContext,\n\tstorage: AbstractStorage,\n\tdraft: PriceDraft,\n): Price => ({\n\tid: uuidv4(),\n\tkey: draft.key,\n\tcountry: draft.country,\n\tvalue: createTypedMoney(draft.value),\n\tchannel: draft.channel\n\t\t? getReferenceFromResourceIdentifier<ChannelReference>(\n\t\t\t\tdraft.channel,\n\t\t\t\tcontext.projectKey,\n\t\t\t\tstorage,\n\t\t\t)\n\t\t: undefined,\n});\n","import type {\n\tCategoryReference,\n\tInvalidJsonInputError,\n\tInvalidOperationError,\n\tPrice,\n\tProduct,\n\tProductAddExternalImageAction,\n\tProductAddPriceAction,\n\tProductAddToCategoryAction,\n\tProductAddVariantAction,\n\tProductChangeMasterVariantAction,\n\tProductChangeNameAction,\n\tProductChangePriceAction,\n\tProductChangeSlugAction,\n\tProductData,\n\tProductMoveImageToPositionAction,\n\tProductPublishAction,\n\tProductRemoveFromCategoryAction,\n\tProductRemoveImageAction,\n\tProductRemovePriceAction,\n\tProductRemoveVariantAction,\n\tProductSetAttributeAction,\n\tProductSetAttributeInAllVariantsAction,\n\tProductSetDescriptionAction,\n\tProductSetKeyAction,\n\tProductSetMetaDescriptionAction,\n\tProductSetMetaKeywordsAction,\n\tProductSetMetaTitleAction,\n\tProductSetProductPriceCustomFieldAction,\n\tProductSetProductPriceCustomTypeAction,\n\tProductSetTaxCategoryAction,\n\tProductTransitionStateAction,\n\tProductUpdateAction,\n\tProductVariantDraft,\n\tStateReference,\n\tTaxCategoryReference,\n} from \"@commercetools/platform-sdk\";\nimport { CommercetoolsError } from \"#src/exceptions.ts\";\nimport type { Writable } from \"#src/types.ts\";\nimport { AbstractUpdateHandler, type RepositoryContext } from \"../abstract.ts\";\nimport {\n\tcreateCustomFields,\n\tgetReferenceFromResourceIdentifier,\n} from \"../helpers.ts\";\nimport {\n\tcheckForStagedChanges,\n\tgetVariant,\n\tpriceFromDraft,\n\tvariantFromDraft,\n} from \"./helpers.ts\";\n\ntype ProductUpdateHandlerMethod<T> = (\n\tcontext: RepositoryContext,\n\tresource: Writable<Product>,\n\taction: T,\n) => void;\n\ntype ProductUpdateActions = Partial<{\n\t[P in ProductUpdateAction as P[\"action\"]]: ProductUpdateHandlerMethod<P>;\n}>;\n\nexport class ProductUpdateHandler\n\textends AbstractUpdateHandler\n\timplements ProductUpdateActions\n{\n\taddExternalImage(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Product>,\n\t\t{ variantId, sku, image, staged }: ProductAddExternalImageAction,\n\t) {\n\t\tconst addImg = (data: Writable<ProductData>) => {\n\t\t\tconst { variant, isMasterVariant, variantIndex } = getVariant(\n\t\t\t\tdata,\n\t\t\t\tvariantId,\n\t\t\t\tsku,\n\t\t\t);\n\t\t\tif (!variant) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Variant with id ${variantId} or sku ${sku} not found on product ${resource.id}`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tif (!variant.images) {\n\t\t\t\tvariant.images = [];\n\t\t\t} else {\n\t\t\t\tconst existingImage = variant.images.find((x) => x.url === image.url);\n\t\t\t\tif (existingImage) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`Cannot add image '${image.url}' because product '${resource.id}' already has that image.`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Add image\n\t\t\tvariant.images.push(image);\n\n\t\t\tif (isMasterVariant) {\n\t\t\t\tdata.masterVariant = variant;\n\t\t\t} else {\n\t\t\t\tdata.variants[variantIndex] = variant;\n\t\t\t}\n\t\t};\n\n\t\t// If true, only the staged Attribute is set. If false, both current and\n\t\t// staged Attribute is set. Default is true\n\t\tconst onlyStaged = staged !== undefined ? staged : true;\n\n\t\t// Write the attribute to the staged data\n\t\taddImg(resource.masterData.staged);\n\n\t\t// Also write to published data is isStaged = false\n\t\t// if isStaged is false we set the attribute on both the staged and\n\t\t// published data.\n\t\tif (!onlyStaged) {\n\t\t\taddImg(resource.masterData.current);\n\t\t}\n\t\tcheckForStagedChanges(resource);\n\n\t\treturn resource;\n\t}\n\n\taddPrice(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Product>,\n\t\t{ variantId, sku, price, staged }: ProductAddPriceAction,\n\t) {\n\t\tconst addVariantPrice = (\n\t\t\tdata: Writable<ProductData>,\n\t\t\tpriceToAdd: Price,\n\t\t) => {\n\t\t\tconst { variant, isMasterVariant, variantIndex } = getVariant(\n\t\t\t\tdata,\n\t\t\t\tvariantId,\n\t\t\t\tsku,\n\t\t\t);\n\t\t\tif (!variant) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Variant with id ${variantId} or sku ${sku} not found on product ${resource.id}`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tif (variant.prices === undefined) {\n\t\t\t\tvariant.prices = [priceToAdd];\n\t\t\t} else {\n\t\t\t\tvariant.prices.push(priceToAdd);\n\t\t\t}\n\n\t\t\tif (isMasterVariant) {\n\t\t\t\tdata.masterVariant = variant;\n\t\t\t} else {\n\t\t\t\tdata.variants[variantIndex] = variant;\n\t\t\t}\n\t\t};\n\n\t\t// Pre-creating the price object ensures consistency between staged and current versions\n\t\tconst priceToAdd = priceFromDraft(context, this._storage, price);\n\n\t\t// If true, only the staged Attribute is set. If false, both current and\n\t\t// staged Attribute is set. Default is true\n\t\tconst onlyStaged = staged !== undefined ? staged : true;\n\n\t\t// Write the attribute to the staged data\n\t\taddVariantPrice(resource.masterData.staged, priceToAdd);\n\n\t\t// Also write to published data is isStaged = false\n\t\t// if isStaged is false we set the attribute on both the staged and\n\t\t// published data.\n\t\tif (!onlyStaged) {\n\t\t\taddVariantPrice(resource.masterData.current, priceToAdd);\n\t\t}\n\t\tcheckForStagedChanges(resource);\n\n\t\treturn resource;\n\t}\n\n\taddToCategory(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Product>,\n\t\t{ category, staged, orderHint }: ProductAddToCategoryAction,\n\t) {\n\t\tconst addCategory = (data: Writable<ProductData>) => {\n\t\t\tif (category) {\n\t\t\t\tdata.categories.push(\n\t\t\t\t\tgetReferenceFromResourceIdentifier<CategoryReference>(\n\t\t\t\t\t\tcategory,\n\t\t\t\t\t\tcontext.projectKey,\n\t\t\t\t\t\tthis._storage,\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tthrow new CommercetoolsError<InvalidJsonInputError>(\n\t\t\t\t\t{\n\t\t\t\t\t\tcode: \"InvalidJsonInput\",\n\t\t\t\t\t\tmessage: \"Request body does not contain valid JSON.\",\n\t\t\t\t\t\tdetailedErrorMessage: \"actions -> category: Missing required value\",\n\t\t\t\t\t},\n\t\t\t\t\t400,\n\t\t\t\t);\n\t\t\t}\n\t\t};\n\n\t\tconst onlyStaged = staged !== undefined ? staged : true;\n\n\t\taddCategory(resource.masterData.staged);\n\n\t\tif (!onlyStaged) {\n\t\t\taddCategory(resource.masterData.current);\n\t\t}\n\t\tcheckForStagedChanges(resource);\n\n\t\treturn resource;\n\t}\n\n\taddVariant(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Product>,\n\t\t{\n\t\t\tsku,\n\t\t\tkey,\n\t\t\tprices,\n\t\t\timages,\n\t\t\tattributes,\n\t\t\tstaged,\n\t\t\tassets,\n\t\t}: ProductAddVariantAction,\n\t) {\n\t\tconst variantDraft: ProductVariantDraft = {\n\t\t\tsku: sku,\n\t\t\tkey: key,\n\t\t\tprices: prices,\n\t\t\timages: images,\n\t\t\tattributes: attributes,\n\t\t\tassets: assets,\n\t\t};\n\n\t\tconst dataStaged = resource.masterData.staged;\n\t\tconst allVariants = [\n\t\t\tdataStaged.masterVariant,\n\t\t\t...(dataStaged.variants ?? []),\n\t\t];\n\t\tconst maxId = allVariants.reduce(\n\t\t\t(max, element) => (element.id > max ? element.id : max),\n\t\t\t0,\n\t\t);\n\t\tconst variant = variantFromDraft(\n\t\t\tcontext,\n\t\t\tthis._storage,\n\t\t\tmaxId + 1,\n\t\t\tvariantDraft,\n\t\t);\n\t\tdataStaged.variants.push(variant);\n\n\t\tconst onlyStaged = staged !== undefined ? staged : true;\n\n\t\tif (!onlyStaged) {\n\t\t\tresource.masterData.current.variants.push(variant);\n\t\t}\n\t\tcheckForStagedChanges(resource);\n\n\t\treturn resource;\n\t}\n\n\tchangeMasterVariant(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Product>,\n\t\t{ variantId, sku, staged }: ProductChangeMasterVariantAction,\n\t) {\n\t\tconst setMaster = (data: Writable<ProductData>) => {\n\t\t\tconst { variant, isMasterVariant, variantIndex } = getVariant(\n\t\t\t\tdata,\n\t\t\t\tvariantId,\n\t\t\t\tsku,\n\t\t\t);\n\t\t\tif (!variant) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Variant with id ${variantId} or sku ${sku} not found on product ${resource.id}`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tif (!isMasterVariant) {\n\t\t\t\t// Save previous master variant\n\t\t\t\tconst masterVariantPrev = data.masterVariant;\n\t\t\t\tdata.masterVariant = variant;\n\t\t\t\t// Remove new master from variants\n\t\t\t\tdata.variants.splice(variantIndex, 1);\n\t\t\t\t// Add previous master to variants\n\t\t\t\tdata.variants.push(masterVariantPrev);\n\t\t\t}\n\t\t};\n\n\t\tconst onlyStaged = staged !== undefined ? staged : true;\n\n\t\tsetMaster(resource.masterData.staged);\n\n\t\tif (!onlyStaged) {\n\t\t\tsetMaster(resource.masterData.current);\n\t\t}\n\t\tcheckForStagedChanges(resource);\n\n\t\treturn resource;\n\t}\n\n\tchangeName(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Product>,\n\t\t{ name, staged }: ProductChangeNameAction,\n\t) {\n\t\tconst onlyStaged = staged !== undefined ? staged : true;\n\t\tresource.masterData.staged.name = name;\n\t\tif (!onlyStaged) {\n\t\t\tresource.masterData.current.name = name;\n\t\t}\n\t\tcheckForStagedChanges(resource);\n\t\treturn resource;\n\t}\n\n\tchangePrice(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Product>,\n\t\t{ priceId, price, staged }: ProductChangePriceAction,\n\t) {\n\t\tconst changeVariantPrice = (data: Writable<ProductData>) => {\n\t\t\tconst allVariants = [data.masterVariant, ...(data.variants ?? [])];\n\t\t\tconst priceVariant = allVariants.find((variant) =>\n\t\t\t\tvariant.prices?.some((x) => x.id === priceId),\n\t\t\t);\n\t\t\tif (!priceVariant) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Price with id ${priceId} not found on product ${resource.id}`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst { variant, isMasterVariant, variantIndex } = getVariant(\n\t\t\t\tdata,\n\t\t\t\tpriceVariant.id,\n\t\t\t\tpriceVariant.sku,\n\t\t\t);\n\t\t\tif (!variant) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Variant with id ${priceVariant.id} or sku ${priceVariant.sku} not found on product ${resource.id}`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tvariant.prices = variant.prices?.map((x) => {\n\t\t\t\tif (x.id === priceId) {\n\t\t\t\t\treturn { ...x, ...price } as Price;\n\t\t\t\t}\n\t\t\t\treturn x;\n\t\t\t});\n\n\t\t\tif (isMasterVariant) {\n\t\t\t\tdata.masterVariant = variant;\n\t\t\t} else {\n\t\t\t\tdata.variants[variantIndex] = variant;\n\t\t\t}\n\t\t};\n\n\t\t// If true, only the staged Attribute is set. If false, both current and\n\t\t// staged Attribute is set. Default is true\n\t\tconst onlyStaged = staged !== undefined ? staged : true;\n\n\t\t// Write the attribute to the staged data\n\t\tchangeVariantPrice(resource.masterData.staged);\n\n\t\t// Also write to published data is isStaged = false\n\t\t// if isStaged is false we set the attribute on both the staged and\n\t\t// published data.\n\t\tif (!onlyStaged) {\n\t\t\tchangeVariantPrice(resource.masterData.current);\n\t\t}\n\t\tcheckForStagedChanges(resource);\n\n\t\treturn resource;\n\t}\n\n\tchangeSlug(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Product>,\n\t\t{ slug, staged }: ProductChangeSlugAction,\n\t) {\n\t\tconst onlyStaged = staged !== undefined ? staged : true;\n\t\tresource.masterData.staged.slug = slug;\n\t\tif (!onlyStaged) {\n\t\t\tresource.masterData.current.slug = slug;\n\t\t}\n\t\tcheckForStagedChanges(resource);\n\t\treturn resource;\n\t}\n\n\tmoveImageToPosition(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Product>,\n\t\t{\n\t\t\tvariantId,\n\t\t\tsku,\n\t\t\timageUrl,\n\t\t\tposition,\n\t\t\tstaged,\n\t\t}: ProductMoveImageToPositionAction,\n\t) {\n\t\tconst moveImg = (data: Writable<ProductData>) => {\n\t\t\tconst { variant, isMasterVariant, variantIndex } = getVariant(\n\t\t\t\tdata,\n\t\t\t\tvariantId,\n\t\t\t\tsku,\n\t\t\t);\n\t\t\tif (!variant) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Variant with id ${variantId} or sku ${sku} not found on product ${resource.id}`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst variantImages = variant.images ?? [];\n\t\t\tconst existingImage = variantImages.find((x) => x.url === imageUrl);\n\t\t\tif (!existingImage) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Cannot move image '${imageUrl}' because product '${resource.id}' does not have that image.`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tif (position >= variantImages.length) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t\"Invalid position given. Position in images where the image should be moved. Must be between 0 and the total number of images minus 1.\",\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Remove image\n\t\t\tvariant.images = variantImages.filter((image) => image.url !== imageUrl);\n\n\t\t\t// Re-add image to the correct position\n\t\t\tvariant.images.splice(position, 0, existingImage);\n\n\t\t\tif (isMasterVariant) {\n\t\t\t\tdata.masterVariant = variant;\n\t\t\t} else {\n\t\t\t\tdata.variants[variantIndex] = variant;\n\t\t\t}\n\t\t};\n\n\t\t// If true, only the staged Attribute is set. If false, both current and\n\t\t// staged Attribute is set. Default is true\n\t\tconst onlyStaged = staged !== undefined ? staged : true;\n\n\t\t// Write the attribute to the staged data\n\t\tmoveImg(resource.masterData.staged);\n\n\t\t// Also write to published data is isStaged = false\n\t\t// if isStaged is false we set the attribute on both the staged and\n\t\t// published data.\n\t\tif (!onlyStaged) {\n\t\t\tmoveImg(resource.masterData.current);\n\t\t}\n\t\tcheckForStagedChanges(resource);\n\n\t\treturn resource;\n\t}\n\n\tpublish(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Product>,\n\t\t{ scope }: ProductPublishAction,\n\t) {\n\t\tresource.masterData.current = resource.masterData.staged;\n\t\tresource.masterData.published = true;\n\t\tcheckForStagedChanges(resource);\n\t}\n\n\tremoveFromCategory(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Product>,\n\t\t{ category, staged }: ProductRemoveFromCategoryAction,\n\t) {\n\t\tconst removeCategory = (data: Writable<ProductData>) => {\n\t\t\tif (category) {\n\t\t\t\tconst resolvedCategory =\n\t\t\t\t\tgetReferenceFromResourceIdentifier<CategoryReference>(\n\t\t\t\t\t\tcategory,\n\t\t\t\t\t\tcontext.projectKey,\n\t\t\t\t\t\tthis._storage,\n\t\t\t\t\t);\n\n\t\t\t\tconst foundCategory = data.categories.find(\n\t\t\t\t\t(productCategory: CategoryReference) => {\n\t\t\t\t\t\tif (productCategory.id === resolvedCategory.id) {\n\t\t\t\t\t\t\treturn productCategory;\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t},\n\t\t\t\t);\n\n\t\t\t\tif (!foundCategory) {\n\t\t\t\t\tthrow new CommercetoolsError<InvalidOperationError>(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcode: \"InvalidOperation\",\n\t\t\t\t\t\t\tmessage:\n\t\t\t\t\t\t\t\t`Cannot remove from category '${resolvedCategory.id}' because product ` +\n\t\t\t\t\t\t\t\t`'${resource.masterData.current.name}' is not in that category.`,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t400,\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tdata.categories = data.categories.filter(\n\t\t\t\t\t(productCategory: CategoryReference) => {\n\t\t\t\t\t\tif (productCategory.id === resolvedCategory.id) {\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tthrow new CommercetoolsError<InvalidJsonInputError>(\n\t\t\t\t\t{\n\t\t\t\t\t\tcode: \"InvalidJsonInput\",\n\t\t\t\t\t\tmessage: \"Request body does not contain valid JSON.\",\n\t\t\t\t\t\tdetailedErrorMessage: \"actions -> category: Missing required value\",\n\t\t\t\t\t},\n\t\t\t\t\t400,\n\t\t\t\t);\n\t\t\t}\n\t\t};\n\n\t\tconst onlyStaged = staged !== undefined ? staged : true;\n\t\tremoveCategory(resource.masterData.staged);\n\n\t\tif (!onlyStaged) {\n\t\t\tremoveCategory(resource.masterData.current);\n\t\t}\n\t\tcheckForStagedChanges(resource);\n\n\t\treturn resource;\n\t}\n\n\tremoveImage(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Product>,\n\t\t{ variantId, sku, imageUrl, staged }: ProductRemoveImageAction,\n\t) {\n\t\tconst removeImg = (data: Writable<ProductData>) => {\n\t\t\tconst { variant, isMasterVariant, variantIndex } = getVariant(\n\t\t\t\tdata,\n\t\t\t\tvariantId,\n\t\t\t\tsku,\n\t\t\t);\n\t\t\tif (!variant) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Variant with id ${variantId} or sku ${sku} not found on product ${resource.id}`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst variantImages = variant.images ?? [];\n\t\t\tconst existingImage = variantImages.find((x) => x.url === imageUrl);\n\t\t\tif (!existingImage) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Cannot remove image '${imageUrl}' because product '${resource.id}' does not have that image.`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Remove image\n\t\t\tvariant.images = variantImages.filter((image) => image.url !== imageUrl);\n\n\t\t\tif (isMasterVariant) {\n\t\t\t\tdata.masterVariant = variant;\n\t\t\t} else {\n\t\t\t\tdata.variants[variantIndex] = variant;\n\t\t\t}\n\t\t};\n\n\t\t// If true, only the staged Attribute is set. If false, both current and\n\t\t// staged Attribute is set. Default is true\n\t\tconst onlyStaged = staged !== undefined ? staged : true;\n\n\t\t// Write the attribute to the staged data\n\t\tremoveImg(resource.masterData.staged);\n\n\t\t// Also write to published data is isStaged = false\n\t\t// if isStaged is false we set the attribute on both the staged and\n\t\t// published data.\n\t\tif (!onlyStaged) {\n\t\t\tremoveImg(resource.masterData.current);\n\t\t}\n\t\tcheckForStagedChanges(resource);\n\n\t\treturn resource;\n\t}\n\n\tremovePrice(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Product>,\n\t\t{ priceId, staged }: ProductRemovePriceAction,\n\t) {\n\t\tconst removeVariantPrice = (data: Writable<ProductData>) => {\n\t\t\tconst allVariants = [data.masterVariant, ...(data.variants ?? [])];\n\t\t\tconst priceVariant = allVariants.find((variant) =>\n\t\t\t\tvariant.prices?.some((x) => x.id === priceId),\n\t\t\t);\n\t\t\tif (!priceVariant) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Price with id ${priceId} not found on product ${resource.id}`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst { variant, isMasterVariant, variantIndex } = getVariant(\n\t\t\t\tdata,\n\t\t\t\tpriceVariant.id,\n\t\t\t\tpriceVariant.sku,\n\t\t\t);\n\t\t\tif (!variant) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Variant with id ${priceVariant.id} or sku ${priceVariant.sku} not found on product ${resource.id}`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tvariant.prices = variant.prices?.filter((x) => x.id !== priceId);\n\n\t\t\tif (isMasterVariant) {\n\t\t\t\tdata.masterVariant = variant;\n\t\t\t} else {\n\t\t\t\tdata.variants[variantIndex] = variant;\n\t\t\t}\n\t\t};\n\n\t\t// If true, only the staged Attribute is set. If false, both current and\n\t\t// staged Attribute is set. Default is true\n\t\tconst onlyStaged = staged !== undefined ? staged : true;\n\n\t\t// Write the attribute to the staged data\n\t\tremoveVariantPrice(resource.masterData.staged);\n\n\t\t// Also write to published data is isStaged = false\n\t\t// if isStaged is false we set the attribute on both the staged and\n\t\t// published data.\n\t\tif (!onlyStaged) {\n\t\t\tremoveVariantPrice(resource.masterData.current);\n\t\t}\n\t\tcheckForStagedChanges(resource);\n\n\t\treturn resource;\n\t}\n\n\tremoveVariant(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Product>,\n\t\t{ id, sku, staged }: ProductRemoveVariantAction,\n\t) {\n\t\tconst removeVariant = (data: Writable<ProductData>) => {\n\t\t\tconst { variant, isMasterVariant, variantIndex } = getVariant(\n\t\t\t\tdata,\n\t\t\t\tid,\n\t\t\t\tsku,\n\t\t\t);\n\t\t\tif (!variant) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Variant with id ${id} or sku ${sku} not found on product ${resource.id}`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (isMasterVariant) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Can not remove the variant [ID:${id}] for [Product:${resource.id}] since it's the master variant`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tdata.variants.splice(variantIndex, 1);\n\t\t};\n\n\t\tconst onlyStaged = staged !== undefined ? staged : true;\n\n\t\tremoveVariant(resource.masterData.staged);\n\n\t\tif (!onlyStaged) {\n\t\t\tremoveVariant(resource.masterData.current);\n\t\t}\n\t\tcheckForStagedChanges(resource);\n\n\t\treturn resource;\n\t}\n\n\tsetAttribute(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Product>,\n\t\t{ variantId, sku, name, value, staged }: ProductSetAttributeAction,\n\t) {\n\t\tconst setAttr = (data: Writable<ProductData>) => {\n\t\t\tconst { variant, isMasterVariant, variantIndex } = getVariant(\n\t\t\t\tdata,\n\t\t\t\tvariantId,\n\t\t\t\tsku,\n\t\t\t);\n\t\t\tif (!variant) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Variant with id ${variantId} or sku ${sku} not found on product ${resource.id}`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tif (!variant.attributes) {\n\t\t\t\tvariant.attributes = [];\n\t\t\t}\n\n\t\t\tconst existingAttr = variant.attributes.find(\n\t\t\t\t(attr) => attr.name === name,\n\t\t\t);\n\t\t\tif (existingAttr) {\n\t\t\t\texistingAttr.value = value;\n\t\t\t} else {\n\t\t\t\tvariant.attributes.push({\n\t\t\t\t\tname,\n\t\t\t\t\tvalue,\n\t\t\t\t});\n\t\t\t}\n\t\t\tif (isMasterVariant) {\n\t\t\t\tdata.masterVariant = variant;\n\t\t\t} else {\n\t\t\t\tdata.variants[variantIndex] = variant;\n\t\t\t}\n\t\t};\n\n\t\t// If true, only the staged Attribute is set. If false, both current and\n\t\t// staged Attribute is set. Default is true\n\t\tconst onlyStaged = staged !== undefined ? staged : true;\n\n\t\t// Write the attribute to the staged data\n\t\tsetAttr(resource.masterData.staged);\n\n\t\t// Also write to published data is isStaged = false\n\t\t// if isStaged is false we set the attribute on both the staged and\n\t\t// published data.\n\t\tif (!onlyStaged) {\n\t\t\tsetAttr(resource.masterData.current);\n\t\t}\n\t\tcheckForStagedChanges(resource);\n\n\t\treturn resource;\n\t}\n\n\tsetAttributeInAllVariants(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Product>,\n\t\t{ name, value, staged }: ProductSetAttributeInAllVariantsAction,\n\t) {\n\t\tconst setAttrInAllVariants = (data: Writable<ProductData>) => {\n\t\t\tif (!data.masterVariant.attributes) {\n\t\t\t\tdata.masterVariant.attributes = [];\n\t\t\t}\n\n\t\t\tconst existingAttr = data.masterVariant.attributes?.find(\n\t\t\t\t(attr) => attr.name === name,\n\t\t\t);\n\n\t\t\tif (existingAttr) {\n\t\t\t\texistingAttr.value = value;\n\t\t\t} else {\n\t\t\t\tdata.masterVariant.attributes.push({\n\t\t\t\t\tname,\n\t\t\t\t\tvalue,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tdata.variants.forEach((variant) => {\n\t\t\t\tif (!variant.attributes) {\n\t\t\t\t\tvariant.attributes = [];\n\t\t\t\t}\n\n\t\t\t\tconst existingAttr = variant.attributes.find(\n\t\t\t\t\t(attr) => attr.name === name,\n\t\t\t\t);\n\t\t\t\tif (existingAttr) {\n\t\t\t\t\texistingAttr.value = value;\n\t\t\t\t} else {\n\t\t\t\t\tvariant.attributes.push({\n\t\t\t\t\t\tname,\n\t\t\t\t\t\tvalue,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t});\n\t\t};\n\n\t\t// If true, only the staged Attribute is set. If false, both current and\n\t\t// staged Attribute is set. Default is true\n\t\tconst onlyStaged = staged !== undefined ? staged : true;\n\n\t\t// Write the attribute to the staged data\n\t\tsetAttrInAllVariants(resource.masterData.staged);\n\n\t\t// Also write to published data is isStaged = false\n\t\t// if isStaged is false we set the attribute on both the staged and\n\t\t// published data.\n\t\tif (!onlyStaged) {\n\t\t\tsetAttrInAllVariants(resource.masterData.current);\n\t\t}\n\t\tcheckForStagedChanges(resource);\n\n\t\treturn resource;\n\t}\n\n\tsetDescription(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Product>,\n\t\t{ description, staged }: ProductSetDescriptionAction,\n\t) {\n\t\tconst onlyStaged = staged !== undefined ? staged : true;\n\n\t\tresource.masterData.staged.description = description;\n\t\tif (!onlyStaged) {\n\t\t\tresource.masterData.current.description = description;\n\t\t}\n\t\tcheckForStagedChanges(resource);\n\t\treturn resource;\n\t}\n\n\tsetKey(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Product>,\n\t\t{ key }: ProductSetKeyAction,\n\t) {\n\t\tresource.key = key;\n\t\treturn resource;\n\t}\n\n\tsetMetaDescription(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Product>,\n\t\t{ metaDescription, staged }: ProductSetMetaDescriptionAction,\n\t) {\n\t\tconst onlyStaged = staged !== undefined ? staged : true;\n\t\tresource.masterData.staged.metaDescription = metaDescription;\n\t\tif (!onlyStaged) {\n\t\t\tresource.masterData.current.metaDescription = metaDescription;\n\t\t}\n\t\tcheckForStagedChanges(resource);\n\t\treturn resource;\n\t}\n\n\tsetMetaKeywords(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Product>,\n\t\t{ metaKeywords, staged }: ProductSetMetaKeywordsAction,\n\t) {\n\t\tconst onlyStaged = staged !== undefined ? staged : true;\n\t\tresource.masterData.staged.metaKeywords = metaKeywords;\n\t\tif (!onlyStaged) {\n\t\t\tresource.masterData.current.metaKeywords = metaKeywords;\n\t\t}\n\t\tcheckForStagedChanges(resource);\n\t\treturn resource;\n\t}\n\n\tsetMetaTitle(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Product>,\n\t\t{ metaTitle, staged }: ProductSetMetaTitleAction,\n\t) {\n\t\tconst onlyStaged = staged !== undefined ? staged : true;\n\t\tresource.masterData.staged.metaTitle = metaTitle;\n\t\tif (!onlyStaged) {\n\t\t\tresource.masterData.current.metaTitle = metaTitle;\n\t\t}\n\t\tcheckForStagedChanges(resource);\n\t\treturn resource;\n\t}\n\n\tsetProductPriceCustomField(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Product>,\n\t\t{ name, value, staged, priceId }: ProductSetProductPriceCustomFieldAction,\n\t) {\n\t\tconst updatePriceCustomFields = (data: Writable<ProductData>) => {\n\t\t\tconst price = [data.masterVariant, ...(data.variants ?? [])]\n\t\t\t\t.flatMap((variant) => variant.prices ?? [])\n\t\t\t\t.find((price) => price.id === priceId);\n\n\t\t\tif (!price) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Price with id ${priceId} not found on product ${resource.id}`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (price.custom) {\n\t\t\t\tif (value === null) {\n\t\t\t\t\tdelete price.custom.fields[name];\n\t\t\t\t} else {\n\t\t\t\t\tprice.custom.fields[name] = value;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn data;\n\t\t};\n\n\t\tresource.masterData.staged = updatePriceCustomFields(\n\t\t\tresource.masterData.staged,\n\t\t);\n\n\t\tconst onlyStaged = staged !== undefined ? staged : true;\n\t\tif (!onlyStaged) {\n\t\t\tresource.masterData.current = updatePriceCustomFields(\n\t\t\t\tresource.masterData.current,\n\t\t\t);\n\t\t}\n\t\tcheckForStagedChanges(resource);\n\t\treturn resource;\n\t}\n\n\tsetProductPriceCustomType(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Product>,\n\t\t{ type, fields, staged, priceId }: ProductSetProductPriceCustomTypeAction,\n\t) {\n\t\tconst updatePriceCustomType = (data: Writable<ProductData>) => {\n\t\t\tconst price = [data.masterVariant, ...(data.variants ?? [])]\n\t\t\t\t.flatMap((variant) => variant.prices ?? [])\n\t\t\t\t.find((price) => price.id === priceId);\n\n\t\t\tif (price) {\n\t\t\t\tif (type) {\n\t\t\t\t\tprice.custom = createCustomFields(\n\t\t\t\t\t\t{ type, fields },\n\t\t\t\t\t\tcontext.projectKey,\n\t\t\t\t\t\tthis._storage,\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\tprice.custom = undefined;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Price with id ${priceId} not found on product ${resource.id}`,\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn data;\n\t\t};\n\n\t\tresource.masterData.staged = updatePriceCustomType(\n\t\t\tresource.masterData.staged,\n\t\t);\n\n\t\tconst onlyStaged = staged !== undefined ? staged : true;\n\t\tif (!onlyStaged) {\n\t\t\tresource.masterData.current = updatePriceCustomType(\n\t\t\t\tresource.masterData.current,\n\t\t\t);\n\t\t}\n\t\tcheckForStagedChanges(resource);\n\t\treturn resource;\n\t}\n\n\tsetTaxCategory(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Product>,\n\t\t{ taxCategory }: ProductSetTaxCategoryAction,\n\t) {\n\t\tlet taxCategoryReference: TaxCategoryReference | undefined;\n\t\tif (taxCategory) {\n\t\t\ttaxCategoryReference =\n\t\t\t\tgetReferenceFromResourceIdentifier<TaxCategoryReference>(\n\t\t\t\t\ttaxCategory,\n\t\t\t\t\tcontext.projectKey,\n\t\t\t\t\tthis._storage,\n\t\t\t\t);\n\t\t} else {\n\t\t\tthrow new CommercetoolsError<InvalidJsonInputError>(\n\t\t\t\t{\n\t\t\t\t\tcode: \"InvalidJsonInput\",\n\t\t\t\t\tmessage: \"Request body does not contain valid JSON.\",\n\t\t\t\t\tdetailedErrorMessage:\n\t\t\t\t\t\t\"actions -> taxCategory: Missing required value\",\n\t\t\t\t},\n\t\t\t\t400,\n\t\t\t);\n\t\t}\n\t\tresource.taxCategory = taxCategoryReference;\n\t\treturn resource;\n\t}\n\n\ttransitionState(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Product>,\n\t\t{ state, force }: ProductTransitionStateAction,\n\t) {\n\t\tlet productStateReference: StateReference | undefined;\n\t\tif (state) {\n\t\t\tproductStateReference =\n\t\t\t\tgetReferenceFromResourceIdentifier<StateReference>(\n\t\t\t\t\tstate,\n\t\t\t\t\tcontext.projectKey,\n\t\t\t\t\tthis._storage,\n\t\t\t\t);\n\t\t\tresource.state = productStateReference;\n\t\t} else {\n\t\t\tthrow new CommercetoolsError<InvalidJsonInputError>(\n\t\t\t\t{\n\t\t\t\t\tcode: \"InvalidJsonInput\",\n\t\t\t\t\tmessage: \"Request body does not contain valid JSON.\",\n\t\t\t\t\tdetailedErrorMessage: \"actions -> state: Missing required value\",\n\t\t\t\t},\n\t\t\t\t400,\n\t\t\t);\n\t\t}\n\n\t\treturn resource;\n\t}\n\n\tunpublish(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Product>,\n\t\t// { action }: ProductUnpublishAction\n\t) {\n\t\tresource.masterData.published = false;\n\t\tcheckForStagedChanges(resource);\n\t}\n\n\t// 'setPrices': () => {},\n\t// 'setDiscountedPrice': () => {},\n\t// 'setAttributeInAllVariants': () => {},\n\t// 'setCategoryOrderHint': () => {},\n\t// 'setSku': () => {},\n\t// 'setProductVariantKey': () => {},\n\t// 'setImageLabel': () => {},\n\t// 'addAsset': () => {},\n\t// 'removeAsset': () => {},\n\t// 'setAssetKey': () => {},\n\t// 'changeAssetOrder': () => {},\n\t// 'changeAssetName': () => {},\n\t// 'setAssetDescription': () => {},\n\t// 'setAssetTags': () => {},\n\t// 'setAssetSources': () => {},\n\t// 'setAssetCustomType': () => {},\n\t// 'setAssetCustomField': () => {},\n\t// 'setSearchKeywords': () => {},\n\t// 'revertStagedChanges': () => {},\n\t// 'revertStagedVariantChanges': () => {},\n}\n","import type {\n\tCategoryReference,\n\tInvalidJsonInputError,\n\tProduct,\n\tProductData,\n\tProductDraft,\n\tProductPagedSearchResponse,\n\tProductSearchRequest,\n\tProductTypeReference,\n\tStateReference,\n\tTaxCategoryReference,\n} from \"@commercetools/platform-sdk\";\nimport type { Config } from \"#src/config.ts\";\nimport { CommercetoolsError } from \"#src/exceptions.ts\";\nimport { getBaseResourceProperties } from \"#src/helpers.ts\";\nimport { ReviewStatisticsService } from \"#src/lib/review-statistics.ts\";\nimport { ProductSearch } from \"#src/product-search.ts\";\nimport type { GetParams, RepositoryContext } from \"../abstract.ts\";\nimport { AbstractResourceRepository } from \"../abstract.ts\";\nimport { getReferenceFromResourceIdentifier } from \"../helpers.ts\";\nimport { ProductUpdateHandler } from \"./actions.ts\";\nimport { variantFromDraft } from \"./helpers.ts\";\n\nexport class ProductRepository extends AbstractResourceRepository<\"product\"> {\n\tprotected _searchService: ProductSearch;\n\tprotected _reviewStatisticsService: ReviewStatisticsService;\n\n\tconstructor(config: Config) {\n\t\tsuper(\"product\", config);\n\t\tthis.actions = new ProductUpdateHandler(config.storage);\n\t\tthis._searchService = new ProductSearch(config);\n\t\tthis._reviewStatisticsService = new ReviewStatisticsService(config.storage);\n\t}\n\n\tcreate(context: RepositoryContext, draft: ProductDraft): Product {\n\t\tif (!draft.masterVariant) {\n\t\t\tthrow new Error(\"Missing master variant\");\n\t\t}\n\n\t\tlet productType: ProductTypeReference | undefined;\n\t\ttry {\n\t\t\tproductType = getReferenceFromResourceIdentifier<ProductTypeReference>(\n\t\t\t\tdraft.productType,\n\t\t\t\tcontext.projectKey,\n\t\t\t\tthis._storage,\n\t\t\t);\n\t\t} catch (err) {\n\t\t\tif (this.config.strict) {\n\t\t\t\tthrow err;\n\t\t\t}\n\n\t\t\t// For now accept missing product types (but warn)\n\t\t\tprocess.emitWarning(\n\t\t\t\t`Error resolving product-type '${draft.productType.id}'. This will be throw an error in later releases.`,\n\t\t\t);\n\t\t\tproductType = {\n\t\t\t\ttypeId: \"product-type\",\n\t\t\t\tid: draft.productType.id || \"\",\n\t\t\t};\n\t\t}\n\n\t\t// Resolve Product categories\n\t\tconst categoryReferences: CategoryReference[] = [];\n\t\tdraft.categories?.forEach((category) => {\n\t\t\tif (category) {\n\t\t\t\tcategoryReferences.push(\n\t\t\t\t\tgetReferenceFromResourceIdentifier<CategoryReference>(\n\t\t\t\t\t\tcategory,\n\t\t\t\t\t\tcontext.projectKey,\n\t\t\t\t\t\tthis._storage,\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tthrow new CommercetoolsError<InvalidJsonInputError>(\n\t\t\t\t\t{\n\t\t\t\t\t\tcode: \"InvalidJsonInput\",\n\t\t\t\t\t\tmessage: \"Request body does not contain valid JSON.\",\n\t\t\t\t\t\tdetailedErrorMessage: \"categories: JSON object expected.\",\n\t\t\t\t\t},\n\t\t\t\t\t400,\n\t\t\t\t);\n\t\t\t}\n\t\t});\n\n\t\t// Resolve Tax category\n\t\tlet taxCategoryReference: TaxCategoryReference | undefined;\n\t\tif (draft.taxCategory) {\n\t\t\ttaxCategoryReference =\n\t\t\t\tgetReferenceFromResourceIdentifier<TaxCategoryReference>(\n\t\t\t\t\tdraft.taxCategory,\n\t\t\t\t\tcontext.projectKey,\n\t\t\t\t\tthis._storage,\n\t\t\t\t);\n\t\t}\n\n\t\t// Resolve Product State\n\t\tlet productStateReference: StateReference | undefined;\n\t\tif (draft.state) {\n\t\t\tproductStateReference =\n\t\t\t\tgetReferenceFromResourceIdentifier<StateReference>(\n\t\t\t\t\tdraft.state,\n\t\t\t\t\tcontext.projectKey,\n\t\t\t\t\tthis._storage,\n\t\t\t\t);\n\t\t}\n\n\t\tconst productData: ProductData = {\n\t\t\tname: draft.name,\n\t\t\tslug: draft.slug,\n\t\t\tdescription: draft.description,\n\t\t\tattributes: draft.attributes ?? [],\n\t\t\tcategories: categoryReferences,\n\t\t\tmasterVariant: variantFromDraft(\n\t\t\t\tcontext,\n\t\t\t\tthis._storage,\n\t\t\t\t1,\n\t\t\t\tdraft.masterVariant,\n\t\t\t),\n\t\t\tvariants:\n\t\t\t\tdraft.variants?.map((variant, index) =>\n\t\t\t\t\tvariantFromDraft(context, this._storage, index + 2, variant),\n\t\t\t\t) ?? [],\n\t\t\tmetaTitle: draft.metaTitle,\n\t\t\tmetaDescription: draft.metaDescription,\n\t\t\tmetaKeywords: draft.metaKeywords,\n\t\t\tsearchKeywords: draft.searchKeywords ?? {},\n\t\t};\n\n\t\tconst resource: Product = {\n\t\t\t...getBaseResourceProperties(),\n\t\t\tkey: draft.key,\n\t\t\tproductType: productType,\n\t\t\ttaxCategory: taxCategoryReference,\n\t\t\tstate: productStateReference,\n\t\t\tmasterData: {\n\t\t\t\tcurrent: productData,\n\t\t\t\tstaged: productData,\n\t\t\t\thasStagedChanges: false,\n\t\t\t\tpublished: draft.publish ?? false,\n\t\t\t},\n\t\t};\n\n\t\treturn this.saveNew(context, resource);\n\t}\n\n\tpostProcessResource(\n\t\tcontext: RepositoryContext,\n\t\tresource: Product,\n\t\tparams?: GetParams,\n\t): Product {\n\t\t// Add review statistics to the product\n\t\tconst reviewStatistics =\n\t\t\tthis._reviewStatisticsService.calculateProductReviewStatistics(\n\t\t\t\tcontext.projectKey,\n\t\t\t\tresource.id,\n\t\t\t);\n\n\t\treturn {\n\t\t\t...resource,\n\t\t\treviewRatingStatistics: reviewStatistics,\n\t\t};\n\t}\n\n\tsearch(\n\t\tcontext: RepositoryContext,\n\t\tsearchRequest: ProductSearchRequest,\n\t): ProductPagedSearchResponse {\n\t\treturn this._searchService.search(context.projectKey, searchRequest);\n\t}\n}\n","import type {\n\tProductDiscount,\n\tProductDiscountChangeIsActiveAction,\n\tProductDiscountChangeNameAction,\n\tProductDiscountChangePredicateAction,\n\tProductDiscountChangeSortOrderAction,\n\tProductDiscountChangeValueAction,\n\tProductDiscountDraft,\n\tProductDiscountSetDescriptionAction,\n\tProductDiscountSetKeyAction,\n\tProductDiscountSetValidFromAction,\n\tProductDiscountSetValidFromAndUntilAction,\n\tProductDiscountSetValidUntilAction,\n\tProductDiscountUpdateAction,\n\tProductDiscountValue,\n\tProductDiscountValueAbsolute,\n\tProductDiscountValueDraft,\n\tProductDiscountValueExternal,\n\tProductDiscountValueRelative,\n} from \"@commercetools/platform-sdk\";\nimport type { Config } from \"#src/config.ts\";\nimport { getBaseResourceProperties } from \"../helpers.ts\";\nimport type { Writable } from \"../types.ts\";\nimport type { RepositoryContext, UpdateHandlerInterface } from \"./abstract.ts\";\nimport {\n\tAbstractResourceRepository,\n\tAbstractUpdateHandler,\n} from \"./abstract.ts\";\nimport { createTypedMoney } from \"./helpers.ts\";\n\nexport class ProductDiscountRepository extends AbstractResourceRepository<\"product-discount\"> {\n\tconstructor(config: Config) {\n\t\tsuper(\"product-discount\", config);\n\t\tthis.actions = new ProductDiscountUpdateHandler(this._storage);\n\t}\n\n\tcreate(\n\t\tcontext: RepositoryContext,\n\t\tdraft: ProductDiscountDraft,\n\t): ProductDiscount {\n\t\tconst resource: ProductDiscount = {\n\t\t\t...getBaseResourceProperties(),\n\t\t\tkey: draft.key,\n\t\t\tname: draft.name,\n\t\t\tdescription: draft.description,\n\t\t\tvalue: transformValueDraft(draft.value),\n\t\t\tpredicate: draft.predicate,\n\t\t\tsortOrder: draft.sortOrder,\n\t\t\tisActive: draft.isActive || false,\n\t\t\tvalidFrom: draft.validFrom,\n\t\t\tvalidUntil: draft.validUntil,\n\t\t\treferences: [],\n\t\t};\n\t\treturn this.saveNew(context, resource);\n\t}\n}\n\nconst transformValueDraft = (\n\tvalue: ProductDiscountValueDraft,\n): ProductDiscountValue => {\n\tswitch (value.type) {\n\t\tcase \"absolute\": {\n\t\t\treturn {\n\t\t\t\ttype: \"absolute\",\n\t\t\t\tmoney: value.money.map(createTypedMoney),\n\t\t\t} as ProductDiscountValueAbsolute;\n\t\t}\n\t\tcase \"external\": {\n\t\t\treturn {\n\t\t\t\ttype: \"external\",\n\t\t\t} as ProductDiscountValueExternal;\n\t\t}\n\t\tcase \"relative\": {\n\t\t\treturn {\n\t\t\t\t...value,\n\t\t\t} as ProductDiscountValueRelative;\n\t\t}\n\t}\n};\n\nexport class ProductDiscountUpdateHandler\n\textends AbstractUpdateHandler\n\timplements\n\t\tUpdateHandlerInterface<ProductDiscount, ProductDiscountUpdateAction>\n{\n\tchangeIsActive(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<ProductDiscount>,\n\t\t{ isActive }: ProductDiscountChangeIsActiveAction,\n\t) {\n\t\tresource.isActive = isActive;\n\t}\n\n\tchangeName(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<ProductDiscount>,\n\t\t{ name }: ProductDiscountChangeNameAction,\n\t) {\n\t\tresource.name = name;\n\t}\n\n\tchangePredicate(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<ProductDiscount>,\n\t\t{ predicate }: ProductDiscountChangePredicateAction,\n\t) {\n\t\tresource.predicate = predicate;\n\t}\n\n\tchangeSortOrder(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<ProductDiscount>,\n\t\t{ sortOrder }: ProductDiscountChangeSortOrderAction,\n\t) {\n\t\tresource.sortOrder = sortOrder;\n\t}\n\n\tchangeValue(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<ProductDiscount>,\n\t\t{ value }: ProductDiscountChangeValueAction,\n\t) {\n\t\tresource.value = transformValueDraft(value);\n\t}\n\n\tsetDescription(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<ProductDiscount>,\n\t\t{ description }: ProductDiscountSetDescriptionAction,\n\t) {\n\t\tif (description && Object.keys(description).length > 0) {\n\t\t\tresource.description = description;\n\t\t} else {\n\t\t\tresource.description = undefined;\n\t\t}\n\t}\n\n\tsetKey(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<ProductDiscount>,\n\t\t{ key }: ProductDiscountSetKeyAction,\n\t) {\n\t\tresource.key = key;\n\t}\n\n\tsetValidFrom(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<ProductDiscount>,\n\t\t{ validFrom }: ProductDiscountSetValidFromAction,\n\t) {\n\t\tresource.validFrom = validFrom;\n\t}\n\n\tsetValidFromAndUntil(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<ProductDiscount>,\n\t\t{ validFrom, validUntil }: ProductDiscountSetValidFromAndUntilAction,\n\t) {\n\t\tresource.validFrom = validFrom;\n\t\tresource.validUntil = validUntil;\n\t}\n\n\tsetValidUntil(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<ProductDiscount>,\n\t\t{ validUntil }: ProductDiscountSetValidUntilAction,\n\t) {\n\t\tresource.validUntil = validUntil;\n\t}\n}\n","export type Location = {\n\tlatitude: number;\n\tlongitude: number;\n};\n\n/**\n * Returns the distance between src and dst as meters\n */\nexport const haversineDistance = (src: Location, dst: Location) => {\n\tconst RADIUS_OF_EARTH_IN_KM = 6371;\n\tconst toRadian = (deg: number) => deg * (Math.PI / 180);\n\n\tconst dLat = toRadian(dst.latitude - src.latitude);\n\tconst dLon = toRadian(dst.longitude - src.longitude);\n\n\tconst a =\n\t\tMath.sin(dLat / 2) * Math.sin(dLat / 2) +\n\t\tMath.cos(toRadian(src.latitude)) *\n\t\t\tMath.cos(toRadian(dst.latitude)) *\n\t\t\tMath.sin(dLon / 2) *\n\t\t\tMath.sin(dLon / 2);\n\tconst c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));\n\treturn RADIUS_OF_EARTH_IN_KM * c * 1000;\n};\n","/**\n * This module implements the commercetools query predicate filter expression.\n * Support should be 100% complete.\n *\n * See https://docs.commercetools.com/api/predicates/query\n */\nimport { haversineDistance } from \"./haversine.ts\";\nimport { type ITokenPosition, Lexer, Parser } from \"./parser.ts\";\n\nexport class PredicateError {\n\tmessage: string;\n\n\tconstructor(message: string) {\n\t\tthis.message = message;\n\t}\n}\n\ntype MatchFunc = (target: any, variables: VariableMap) => boolean;\ntype VariableMap = {\n\t[key: string]: any;\n};\n\nexport const matchesPredicate = (\n\tpredicate: string | string[] | undefined,\n\ttarget: any,\n\tvariables?: VariableMap,\n): boolean => {\n\tif (!predicate) {\n\t\treturn true;\n\t}\n\n\tif (Array.isArray(predicate)) {\n\t\treturn predicate.every((item) => {\n\t\t\tconst func = generateMatchFunc(item);\n\t\t\treturn func(target, variables ?? {});\n\t\t});\n\t}\n\tconst func = generateMatchFunc(predicate);\n\treturn func(target, variables ?? {});\n};\n\nexport const parseQueryExpression = (\n\tpredicate: string | string[],\n): MatchFunc => {\n\tif (Array.isArray(predicate)) {\n\t\tconst callbacks = predicate.map((item) => generateMatchFunc(item));\n\t\treturn (target: any, variables: VariableMap) =>\n\t\t\tcallbacks.every((callback) => callback(target, variables));\n\t}\n\treturn generateMatchFunc(predicate);\n};\n\ntype TypeSymbol = {\n\ttype: \"var\" | \"boolean\" | \"string\" | \"float\" | \"int\" | \"identifier\";\n\tvalue: any;\n\tpos?: ITokenPosition;\n};\n\nconst validateSymbol = (val: TypeSymbol) => {\n\tif (!val.type) {\n\t\tthrow new PredicateError(\"Internal error\");\n\t}\n\n\tif (val.type === \"identifier\") {\n\t\tconst char = val.value.charAt(0);\n\t\tconst line = val.pos?.start.line;\n\t\tconst column = val.pos?.start.column;\n\n\t\tthrow new PredicateError(\n\t\t\t`Invalid input '${char}', expected input parameter or primitive value (line ${line}, column ${column})`,\n\t\t);\n\t}\n};\n\nconst resolveSymbol = (val: TypeSymbol, vars: VariableMap): any => {\n\tif (val.type === \"var\") {\n\t\tif (!(val.value in (vars ?? {}))) {\n\t\t\tthrow new PredicateError(`Missing parameter value for ${val.value}`);\n\t\t}\n\t\treturn vars[val.value];\n\t}\n\n\treturn val.value;\n};\n\nconst resolveValue = (obj: any, val: TypeSymbol): any => {\n\tif (val.type !== \"identifier\") {\n\t\tthrow new PredicateError(\"Internal error\");\n\t}\n\n\t// variants() includes both masterVariant and variants for predicates\n\tif (\n\t\tval.value === \"variants\" &&\n\t\tobj.masterVariant &&\n\t\tobj.variants !== undefined\n\t) {\n\t\treturn [obj.masterVariant, ...(obj.variants ?? [])];\n\t}\n\n\tif (!(val.value in obj)) {\n\t\tif (Array.isArray(obj)) {\n\t\t\treturn Object.values(obj)\n\t\t\t\t.filter((v) => val.value in v)\n\t\t\t\t.map((v) => v[val.value]);\n\t\t}\n\n\t\t// TODO: We don't really validate the shape of the object here. To actually\n\t\t// match commercetools behaviour we should throw an error if the requested\n\t\t// field doesn't exist (unless it's a map)\n\t\t// throw new PredicateError(`The field '${val.value}' does not exist.`)\n\t\treturn undefined;\n\t}\n\n\treturn obj[val.value];\n};\n\nconst getLexer = (value: string) =>\n\tnew Lexer(value)\n\n\t\t.token(\"AND\", /and(?![-_a-z0-9]+)/i)\n\t\t.token(\"OR\", /or(?![-_a-z0-9]+)/i)\n\t\t.token(\"NOT\", /not(?![-_a-z0-9]+)/i)\n\n\t\t.token(\"WITHIN\", /within(?![-_a-z0-9]+)/i)\n\t\t.token(\"IN\", /in(?![-_a-z0-9]+)/i)\n\t\t.token(\"MATCHES_IGNORE_CASE\", /matches\\s+ignore\\s+case(?![-_a-z0-9]+)/i)\n\t\t.token(\"CONTAINS\", /contains(?![-_a-z0-9]+)/i)\n\t\t.token(\"ALL\", /all(?![-_a-z0-9]+)/i)\n\t\t.token(\"ANY\", /any(?![-_a-z0-9]+)/i)\n\t\t.token(\"EMPTY\", /empty(?![-_a-z0-9]+)/i)\n\t\t.token(\"IS\", /is(?![-_a-z0-9]+)/i)\n\t\t.token(\"DEFINED\", /defined(?![-_a-z0-9]+)/i)\n\n\t\t// Special case for UUID identifiers,\n\t\t// since they otherwise would get matched as INT, when starting with a digit\n\t\t.token(\n\t\t\t\"IDENTIFIER\",\n\t\t\t/[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}/,\n\t\t)\n\t\t.token(\"FLOAT\", /\\d+\\.\\d+/)\n\t\t.token(\"INT\", /\\d+/)\n\t\t.token(\"VARIABLE\", /:([-_A-Za-z0-9]+)/)\n\t\t.token(\"BOOLEAN\", /(true|false)/)\n\t\t.token(\"IDENTIFIER\", /[-_A-Za-z0-9]+/)\n\t\t.token(\"STRING\", /\"((?:\\\\.|[^\"\\\\])*)\"/)\n\t\t.token(\"STRING\", /'((?:\\\\.|[^'\\\\])*)'/)\n\n\t\t.token(\"COMMA\", \",\")\n\t\t.token(\"(\", \"(\")\n\t\t.token(\")\", \")\")\n\t\t.token(\">=\", \">=\")\n\t\t.token(\"<=\", \"<=\")\n\t\t.token(\">\", \">\")\n\t\t.token(\"<\", \"<\")\n\t\t.token(\"!=\", \"!=\")\n\t\t.token(\"=\", \"=\")\n\t\t.token('\"', '\"')\n\t\t.token(\"WS\", /\\s+/, true); // skip\n\n/**\n * This function converts a query expression in to a callable which returns a\n * boolean to indicate if the given object matches or not.\n *\n * This currently parses the predicate each time it is called, but it should be\n * straight-forward to add a query cache (lru-cache)\n */\nconst generateMatchFunc = (predicate: string): MatchFunc => {\n\tconst lexer = getLexer(predicate);\n\tconst parser = new Parser(lexer)\n\t\t.builder()\n\t\t.nud(\n\t\t\t\"IDENTIFIER\",\n\t\t\t100,\n\t\t\t(t) =>\n\t\t\t\t({\n\t\t\t\t\ttype: \"identifier\",\n\t\t\t\t\tvalue: t.token.match,\n\t\t\t\t\tpos: t.token.strpos(),\n\t\t\t\t}) as TypeSymbol,\n\t\t)\n\t\t.nud(\n\t\t\t\"BOOLEAN\",\n\t\t\t1,\n\t\t\t(t) =>\n\t\t\t\t({\n\t\t\t\t\ttype: \"boolean\",\n\t\t\t\t\tvalue: t.token.match === \"true\",\n\t\t\t\t\tpos: t.token.strpos(),\n\t\t\t\t}) as TypeSymbol,\n\t\t)\n\t\t.nud(\n\t\t\t\"VARIABLE\",\n\t\t\t100,\n\t\t\t(t) =>\n\t\t\t\t({\n\t\t\t\t\ttype: \"var\",\n\t\t\t\t\t// @ts-expect-error\n\t\t\t\t\tvalue: t.token.groups[1],\n\t\t\t\t\tpos: t.token.strpos(),\n\t\t\t\t}) as TypeSymbol,\n\t\t)\n\t\t.nud(\n\t\t\t\"STRING\",\n\t\t\t100,\n\t\t\t(t) =>\n\t\t\t\t({\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t// @ts-expect-error\n\t\t\t\t\tvalue: t.token.groups[1],\n\t\t\t\t\tpos: t.token.strpos(),\n\t\t\t\t}) as TypeSymbol,\n\t\t)\n\t\t.nud(\n\t\t\t\"INT\",\n\t\t\t1,\n\t\t\t(t) =>\n\t\t\t\t({\n\t\t\t\t\ttype: \"int\",\n\t\t\t\t\tvalue: Number.parseInt(t.token.match, 10),\n\t\t\t\t\tpos: t.token.strpos(),\n\t\t\t\t}) as TypeSymbol,\n\t\t)\n\t\t.nud(\n\t\t\t\"FLOAT\",\n\t\t\t1,\n\t\t\t(t) =>\n\t\t\t\t({\n\t\t\t\t\ttype: \"float\",\n\t\t\t\t\tvalue: Number.parseFloat(t.token.match),\n\t\t\t\t\tpos: t.token.strpos(),\n\t\t\t\t}) as TypeSymbol,\n\t\t)\n\t\t.nud(\"NOT\", 100, ({ bp }) => {\n\t\t\tconst expr = parser.parse({ terminals: [bp - 1] });\n\t\t\treturn (obj: any) => !expr(obj);\n\t\t})\n\t\t.nud(\"EMPTY\", 10, ({ bp }) => \"empty\")\n\t\t.nud(\"DEFINED\", 10, ({ bp }) => \"defined\")\n\n\t\t.led(\"AND\", 5, ({ left, bp }) => {\n\t\t\tconst expr = parser.parse({ terminals: [bp - 1] });\n\t\t\treturn (obj: any, vars: object) => left(obj, vars) && expr(obj, vars);\n\t\t})\n\t\t.led(\"OR\", 5, ({ left, token, bp }) => {\n\t\t\tconst expr = parser.parse({ terminals: [bp - 1] });\n\t\t\treturn (obj: any, vars: object) => left(obj, vars) || expr(obj, vars);\n\t\t})\n\t\t.led(\"COMMA\", 1, ({ left, token, bp }) => {\n\t\t\tconst expr: any = parser.parse({ terminals: [bp - 1] });\n\t\t\tif (Array.isArray(expr)) {\n\t\t\t\treturn [left, ...expr];\n\t\t\t}\n\t\t\treturn [left, expr];\n\t\t})\n\t\t.nud(\"(\", 100, (t) => {\n\t\t\tconst expr: any = parser.parse({ terminals: [\")\"] });\n\t\t\treturn expr;\n\t\t})\n\t\t.led(\"(\", 100, ({ left, bp }) => {\n\t\t\tconst expr = parser.parse();\n\t\t\tlexer.expect(\")\");\n\t\t\treturn (obj: any, vars: object) => {\n\t\t\t\tif (Array.isArray(obj)) {\n\t\t\t\t\treturn obj.some((item) => {\n\t\t\t\t\t\tconst value = resolveValue(item, left);\n\t\t\t\t\t\tif (value) {\n\t\t\t\t\t\t\treturn expr(value, vars);\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tconst value = resolveValue(obj, left);\n\t\t\t\tif (value) {\n\t\t\t\t\tif (Array.isArray(value)) {\n\t\t\t\t\t\treturn value.some((item) => expr(item, vars));\n\t\t\t\t\t}\n\n\t\t\t\t\treturn expr(value, vars);\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t};\n\t\t})\n\t\t.bp(\")\", 0)\n\t\t.led(\"=\", 20, ({ left, bp }) => {\n\t\t\tconst expr = parser.parse({ terminals: [bp - 1] });\n\t\t\tvalidateSymbol(expr);\n\n\t\t\treturn (obj: any, vars: VariableMap) => {\n\t\t\t\tif (Array.isArray(obj)) {\n\t\t\t\t\treturn obj.some((item) => {\n\t\t\t\t\t\tconst value = resolveValue(item, left);\n\t\t\t\t\t\tconst other = resolveSymbol(expr, vars);\n\t\t\t\t\t\tif (Array.isArray(value)) {\n\t\t\t\t\t\t\treturn !!value.some((elem) => elem === other);\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn value === other;\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tconst resolvedValue = resolveValue(obj, left);\n\t\t\t\tconst resolvedSymbol = resolveSymbol(expr, vars);\n\t\t\t\tif (Array.isArray(resolvedValue)) {\n\t\t\t\t\treturn !!resolvedValue.some((elem) => elem === resolvedSymbol);\n\t\t\t\t}\n\t\t\t\treturn resolvedValue === resolvedSymbol;\n\t\t\t};\n\t\t})\n\t\t.led(\"!=\", 20, ({ left, bp }) => {\n\t\t\tconst expr = parser.parse({ terminals: [bp - 1] });\n\t\t\tvalidateSymbol(expr);\n\t\t\treturn (obj: any, vars: VariableMap) =>\n\t\t\t\tresolveValue(obj, left) !== resolveSymbol(expr, vars);\n\t\t})\n\t\t.led(\">\", 20, ({ left, bp }) => {\n\t\t\tconst expr = parser.parse({ terminals: [bp - 1] });\n\t\t\tvalidateSymbol(expr);\n\n\t\t\treturn (obj: any, vars: object) =>\n\t\t\t\tresolveValue(obj, left) > resolveSymbol(expr, vars);\n\t\t})\n\t\t.led(\">=\", 20, ({ left, bp }) => {\n\t\t\tconst expr = parser.parse({ terminals: [bp - 1] });\n\t\t\tvalidateSymbol(expr);\n\n\t\t\treturn (obj: any, vars: object) =>\n\t\t\t\tresolveValue(obj, left) >= resolveSymbol(expr, vars);\n\t\t})\n\t\t.led(\"<\", 20, ({ left, bp }) => {\n\t\t\tconst expr = parser.parse({ terminals: [bp - 1] });\n\t\t\tvalidateSymbol(expr);\n\n\t\t\treturn (obj: any, vars: object) =>\n\t\t\t\tresolveValue(obj, left) < resolveSymbol(expr, vars);\n\t\t})\n\t\t.led(\"<=\", 20, ({ left, bp }) => {\n\t\t\tconst expr = parser.parse({ terminals: [bp - 1] });\n\t\t\tvalidateSymbol(expr);\n\n\t\t\treturn (obj: any, vars: object) =>\n\t\t\t\tresolveValue(obj, left) <= resolveSymbol(expr, vars);\n\t\t})\n\t\t.led(\"IS\", 20, ({ left, bp }) => {\n\t\t\tlet invert = false;\n\n\t\t\t// Peek if this is a `is not` statement\n\t\t\tconst next = lexer.peek();\n\t\t\tif (next.type === \"NOT\") {\n\t\t\t\tinvert = true;\n\t\t\t\tlexer.next();\n\t\t\t}\n\n\t\t\tconst expr: any = parser.parse({ terminals: [bp - 1] });\n\n\t\t\tswitch (expr) {\n\t\t\t\tcase \"empty\": {\n\t\t\t\t\tif (!invert) {\n\t\t\t\t\t\treturn (obj: any, vars: VariableMap) => {\n\t\t\t\t\t\t\tconst val = resolveValue(obj, left);\n\t\t\t\t\t\t\treturn val.length === 0;\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t\treturn (obj: any, vars: VariableMap) => {\n\t\t\t\t\t\tconst val = resolveValue(obj, left);\n\t\t\t\t\t\treturn val.length !== 0;\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\tcase \"defined\": {\n\t\t\t\t\tif (!invert) {\n\t\t\t\t\t\treturn (obj: any, vars: VariableMap) => {\n\t\t\t\t\t\t\tconst val = resolveValue(obj, left);\n\t\t\t\t\t\t\treturn val !== undefined;\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t\treturn (obj: any, vars: VariableMap) => {\n\t\t\t\t\t\tconst val = resolveValue(obj, left);\n\t\t\t\t\t\treturn val === undefined;\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\tdefault: {\n\t\t\t\t\tthrow new Error(\"Unexpected\");\n\t\t\t\t}\n\t\t\t}\n\t\t})\n\t\t.led(\"IN\", 20, ({ left, bp }) => {\n\t\t\tconst firstToken = lexer.peek();\n\t\t\tconst expr = parser.parse({ terminals: [bp - 1] });\n\n\t\t\t// IN can be a single value or a list of values\n\t\t\tif (firstToken.match === \"(\") {\n\t\t\t\tlexer.expect(\")\");\n\t\t\t}\n\n\t\t\treturn (obj: any, vars: object) => {\n\t\t\t\tlet symbols = expr;\n\t\t\t\tif (!Array.isArray(symbols)) {\n\t\t\t\t\tsymbols = [expr];\n\t\t\t\t}\n\n\t\t\t\t// The expression can be a list of variables, like\n\t\t\t\t// :value_1, :value_2, but it can also be one variable\n\t\t\t\t// containing a list, like :values.\n\t\t\t\t// So to support both we just flatten the list.\n\t\t\t\tconst inValues = symbols.flatMap((item: TypeSymbol) =>\n\t\t\t\t\tresolveSymbol(item, vars),\n\t\t\t\t);\n\t\t\t\tconst value = resolveValue(obj, left);\n\n\t\t\t\tif (Array.isArray(value)) {\n\t\t\t\t\treturn inValues.some((inValue: any) => value.includes(inValue));\n\t\t\t\t}\n\n\t\t\t\treturn inValues.includes(value);\n\t\t\t};\n\t\t})\n\t\t.led(\"MATCHES_IGNORE_CASE\", 20, ({ left, bp }) => {\n\t\t\tconst expr = parser.parse({ terminals: [bp - 1] });\n\t\t\tvalidateSymbol(expr);\n\n\t\t\treturn (obj: any, vars: VariableMap) => {\n\t\t\t\tconst value = resolveValue(obj, left);\n\t\t\t\tconst other = resolveSymbol(expr, vars);\n\n\t\t\t\tif (typeof value !== \"string\") {\n\t\t\t\t\tthrow new PredicateError(\n\t\t\t\t\t\t`The field '${left.value}' does not support this expression.`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\treturn value.toLowerCase() === other.toLowerCase();\n\t\t\t};\n\t\t})\n\t\t.led(\"WITHIN\", 20, ({ left, bp }) => {\n\t\t\tconst type = lexer.next();\n\n\t\t\tif (type.match !== \"circle\") {\n\t\t\t\tthrow new PredicateError(\n\t\t\t\t\t`Invalid input '${type.match}', expected circle`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tlexer.expect(\"(\");\n\t\t\tconst expr = parser.parse({ terminals: [\")\"] });\n\t\t\tlexer.expect(\")\");\n\n\t\t\treturn (obj: any, vars: object) => {\n\t\t\t\tconst value = resolveValue(obj, left);\n\t\t\t\tif (!value) return false;\n\n\t\t\t\tconst maxDistance = resolveSymbol(expr[2], vars);\n\t\t\t\tconst distance = haversineDistance(\n\t\t\t\t\t{\n\t\t\t\t\t\tlongitude: value[0],\n\t\t\t\t\t\tlatitude: value[1],\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tlongitude: resolveSymbol(expr[0], vars),\n\t\t\t\t\t\tlatitude: resolveSymbol(expr[1], vars),\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t\treturn distance <= maxDistance;\n\t\t\t};\n\t\t})\n\t\t.led(\"CONTAINS\", 20, ({ left, bp }) => {\n\t\t\tconst keyword = lexer.next();\n\n\t\t\tlet expr = parser.parse();\n\t\t\tif (!Array.isArray(expr)) {\n\t\t\t\texpr = [expr];\n\t\t\t}\n\n\t\t\treturn (obj: any, vars: object) => {\n\t\t\t\tconst value = resolveValue(obj, left);\n\n\t\t\t\tif (!Array.isArray(value)) {\n\t\t\t\t\tthrow new PredicateError(\n\t\t\t\t\t\t`The field '${left.value}' does not support this expression.`,\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tconst array = expr.map((item: TypeSymbol) => resolveSymbol(item, vars));\n\t\t\t\tif (keyword.type === \"ALL\") {\n\t\t\t\t\treturn array.every((item: any) => value.includes(item));\n\t\t\t\t}\n\t\t\t\treturn array.some((item: any) => value.includes(item));\n\t\t\t};\n\t\t})\n\n\t\t.build();\n\n\tconst result = parser.parse();\n\n\tif (typeof result !== \"function\") {\n\t\tconst lines = predicate.split(\"\\n\");\n\t\tconst column = lines[lines.length - 1].length;\n\n\t\tthrow new PredicateError(\n\t\t\t`Unexpected end of input, expected SphereIdentifierChar, comparison operator, not, in, contains, is, within or matches (line ${lines.length}, column ${column})`,\n\t\t);\n\t}\n\treturn result;\n};\n","import type {\n\tFacetResults,\n\tFilteredFacetResult,\n\tInvalidInputError,\n\tProduct,\n\tProductProjection,\n\tProductProjectionPagedSearchResponse,\n\tQueryParam,\n\tRangeFacetResult,\n\tTermFacetResult,\n} from \"@commercetools/platform-sdk\";\nimport type { Config } from \"./config.ts\";\nimport { CommercetoolsError } from \"./exceptions.ts\";\nimport { nestedLookup } from \"./helpers.ts\";\nimport type {\n\tFilterExpression,\n\tRangeExpression,\n} from \"./lib/projectionSearchFilter.ts\";\nimport {\n\tgenerateFacetFunc,\n\tgetVariants,\n\tparseFilterExpression,\n\tresolveVariantValue,\n} from \"./lib/projectionSearchFilter.ts\";\nimport { ReviewStatisticsService } from \"./lib/review-statistics.ts\";\nimport { applyPriceSelector } from \"./priceSelector.ts\";\nimport type { AbstractStorage } from \"./storage/index.ts\";\nimport type { Writable } from \"./types.ts\";\n\nexport type ProductProjectionSearchParams = {\n\tfuzzy?: boolean;\n\tfuzzyLevel?: number;\n\tmarkMatchingVariants?: boolean;\n\tstaged?: boolean;\n\tfilter?: string[];\n\t\"filter.facets\"?: string[];\n\t\"filter.query\"?: string[];\n\tfacet?: string | string[];\n\tsort?: string | string[];\n\tlimit?: number;\n\toffset?: number;\n\twithTotal?: boolean;\n\tpriceCurrency?: string;\n\tpriceCountry?: string;\n\tpriceCustomerGroup?: string;\n\tpriceChannel?: string;\n\tlocaleProjection?: string;\n\tstoreProjection?: string;\n\texpand?: string | string[];\n\t[key: string]: QueryParam;\n};\n\nexport class ProductProjectionSearch {\n\tprotected _storage: AbstractStorage;\n\tprotected _reviewStatisticsService: ReviewStatisticsService;\n\n\tconstructor(config: Config) {\n\t\tthis._storage = config.storage;\n\t\tthis._reviewStatisticsService = new ReviewStatisticsService(config.storage);\n\t}\n\n\tsearch(\n\t\tprojectKey: string,\n\t\tparams: ProductProjectionSearchParams,\n\t): ProductProjectionPagedSearchResponse {\n\t\tlet resources = this._storage\n\t\t\t.all(projectKey, \"product\")\n\t\t\t.map((r) => this.transform(r, params.staged ?? false, projectKey))\n\t\t\t.filter((p) => {\n\t\t\t\tif (!(params.staged ?? false)) {\n\t\t\t\t\treturn p.published;\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t});\n\n\t\tconst markMatchingVariant = params.markMatchingVariants ?? false;\n\n\t\t// Apply the priceSelector\n\t\tapplyPriceSelector(resources, {\n\t\t\tcountry: params.priceCountry,\n\t\t\tchannel: params.priceChannel,\n\t\t\tcustomerGroup: params.priceCustomerGroup,\n\t\t\tcurrency: params.priceCurrency,\n\t\t});\n\n\t\t// Apply filters pre faceting\n\t\tif (params.filter) {\n\t\t\ttry {\n\t\t\t\tconst filters = params.filter.map(parseFilterExpression);\n\n\t\t\t\t// Filters can modify the output. So clone the resources first.\n\t\t\t\tresources = resources.filter((resource) =>\n\t\t\t\t\tfilters.every((f) => f(resource, markMatchingVariant)),\n\t\t\t\t);\n\t\t\t} catch (err) {\n\t\t\t\tthrow new CommercetoolsError<InvalidInputError>(\n\t\t\t\t\t{\n\t\t\t\t\t\tcode: \"InvalidInput\",\n\t\t\t\t\t\tmessage: (err as any).message,\n\t\t\t\t\t},\n\t\t\t\t\t400,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\t// TODO: Calculate facets\n\t\tconst facets = this.getFacets(params, resources);\n\n\t\t// Apply filters post facetting\n\t\tif (params[\"filter.query\"]) {\n\t\t\ttry {\n\t\t\t\tconst filters = params[\"filter.query\"].map(parseFilterExpression);\n\t\t\t\tresources = resources.filter((resource) =>\n\t\t\t\t\tfilters.every((f) => f(resource, markMatchingVariant)),\n\t\t\t\t);\n\t\t\t} catch (err) {\n\t\t\t\tthrow new CommercetoolsError<InvalidInputError>(\n\t\t\t\t\t{\n\t\t\t\t\t\tcode: \"InvalidInput\",\n\t\t\t\t\t\tmessage: (err as any).message,\n\t\t\t\t\t},\n\t\t\t\t\t400,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\t// Expand the resources\n\t\tif (params.expand !== undefined) {\n\t\t\tresources = resources.map((resource) =>\n\t\t\t\tthis._storage.expand(projectKey, resource, params.expand),\n\t\t\t);\n\t\t}\n\n\t\t// Create a slice for the pagination. If we were working with large datasets\n\t\t// then we should have done this before transforming. But that isn't the\n\t\t// goal of this library. So lets keep it simple.\n\t\tconst totalResults = resources.length;\n\t\tconst offset = params.offset || 0;\n\t\tconst limit = params.limit || 20;\n\t\tconst results = resources.slice(offset, offset + limit);\n\n\t\treturn {\n\t\t\tcount: totalResults,\n\t\t\ttotal: results.length,\n\t\t\toffset: offset,\n\t\t\tlimit: limit,\n\t\t\tresults: results,\n\t\t\tfacets: facets,\n\t\t};\n\t}\n\n\ttransform(\n\t\tproduct: Product,\n\t\tstaged: boolean,\n\t\tprojectKey: string,\n\t): ProductProjection {\n\t\tconst obj = !staged\n\t\t\t? product.masterData.current\n\t\t\t: product.masterData.staged;\n\n\t\t// Calculate review statistics for this product\n\t\tconst reviewRatingStatistics =\n\t\t\tthis._reviewStatisticsService.calculateProductReviewStatistics(\n\t\t\t\tprojectKey,\n\t\t\t\tproduct.id,\n\t\t\t);\n\n\t\treturn {\n\t\t\tid: product.id,\n\t\t\tcreatedAt: product.createdAt,\n\t\t\tattributes: obj.attributes,\n\t\t\tlastModifiedAt: product.lastModifiedAt,\n\t\t\tversion: product.version,\n\t\t\tname: obj.name,\n\t\t\tkey: product.key,\n\t\t\tdescription: obj.description,\n\t\t\tmetaDescription: obj.metaDescription,\n\t\t\tslug: obj.slug,\n\t\t\tcategories: obj.categories,\n\t\t\tmasterVariant: obj.masterVariant,\n\t\t\tvariants: obj.variants,\n\t\t\tproductType: product.productType,\n\t\t\thasStagedChanges: product.masterData.hasStagedChanges,\n\t\t\tpublished: product.masterData.published,\n\t\t\treviewRatingStatistics,\n\t\t};\n\t}\n\n\tgetFacets(\n\t\tparams: ProductProjectionSearchParams,\n\t\tproducts: ProductProjection[],\n\t): FacetResults {\n\t\tif (!params.facet) return {};\n\t\tconst result: FacetResults = {};\n\n\t\tconst regexp = new RegExp(/ counting products$/);\n\t\tfor (let facet of params.facet) {\n\t\t\tlet countProducts = false;\n\t\t\tif (facet.endsWith(\" counting products\")) {\n\t\t\t\tfacet = facet.replace(regexp, \"\");\n\t\t\t\tcountProducts = true;\n\t\t\t}\n\n\t\t\tconst expression = generateFacetFunc(facet);\n\n\t\t\t// Term Facet\n\t\t\tif (expression.type === \"TermExpression\") {\n\t\t\t\tresult[facet] = this.termFacet(\n\t\t\t\t\texpression.source,\n\t\t\t\t\tproducts,\n\t\t\t\t\tcountProducts,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Range Facet\n\t\t\tif (expression.type === \"RangeExpression\") {\n\t\t\t\tresult[expression.source] = this.rangeFacet(\n\t\t\t\t\texpression.source,\n\t\t\t\t\texpression.children,\n\t\t\t\t\tproducts,\n\t\t\t\t\tcountProducts,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// FilteredFacet\n\t\t\tif (expression.type === \"FilterExpression\") {\n\t\t\t\tresult[expression.source] = this.filterFacet(\n\t\t\t\t\texpression.source,\n\t\t\t\t\texpression.children,\n\t\t\t\t\tproducts,\n\t\t\t\t\tcountProducts,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\treturn result;\n\t}\n\n\t/**\n\t * TODO: This implemention needs the following additional features:\n\t * - counting products\n\t * - correct dataType\n\t */\n\ttermFacet(\n\t\tfacet: string,\n\t\tproducts: ProductProjection[],\n\t\tcountProducts: boolean,\n\t): TermFacetResult {\n\t\tconst result: Writable<TermFacetResult> = {\n\t\t\ttype: \"terms\",\n\t\t\tdataType: \"text\",\n\t\t\tmissing: 0,\n\t\t\ttotal: 0,\n\t\t\tother: 0,\n\t\t\tterms: [],\n\t\t};\n\t\tconst terms: Record<any, number> = {};\n\n\t\tif (facet.startsWith(\"variants.\")) {\n\t\t\tfor (const p of products) {\n\t\t\t\tconst variants = getVariants(p);\n\t\t\t\tfor (const v of variants) {\n\t\t\t\t\tresult.total++;\n\n\t\t\t\t\tlet value = resolveVariantValue(v, facet);\n\t\t\t\t\tif (value === undefined) {\n\t\t\t\t\t\tresult.missing++;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif (typeof value === \"number\") {\n\t\t\t\t\t\t\tvalue = Number(value).toFixed(1);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tterms[value] = value in terms ? terms[value] + 1 : 1;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tfor (const p of products) {\n\t\t\t\tconst value = nestedLookup(p, facet);\n\t\t\t\tresult.total++;\n\t\t\t\tif (value === undefined) {\n\t\t\t\t\tresult.missing++;\n\t\t\t\t} else {\n\t\t\t\t\tterms[value] = value in terms ? terms[value] + 1 : 1;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tfor (const term in terms) {\n\t\t\tresult.terms.push({\n\t\t\t\tterm: term as any,\n\t\t\t\tcount: terms[term],\n\t\t\t});\n\t\t}\n\n\t\treturn result;\n\t}\n\n\tfilterFacet(\n\t\tsource: string,\n\t\tfilters: FilterExpression[] | undefined,\n\t\tproducts: ProductProjection[],\n\t\tcountProducts: boolean,\n\t): FilteredFacetResult {\n\t\tlet count = 0;\n\t\tif (source.startsWith(\"variants.\")) {\n\t\t\tfor (const p of products) {\n\t\t\t\tfor (const v of getVariants(p)) {\n\t\t\t\t\tconst val = resolveVariantValue(v, source);\n\t\t\t\t\tif (filters?.some((f) => f.match(val))) {\n\t\t\t\t\t\tcount++;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tthrow new Error(\"not supported\");\n\t\t}\n\n\t\treturn {\n\t\t\ttype: \"filter\",\n\t\t\tcount: count,\n\t\t};\n\t}\n\n\trangeFacet(\n\t\tsource: string,\n\t\tranges: RangeExpression[] | undefined,\n\t\tproducts: ProductProjection[],\n\t\tcountProducts: boolean,\n\t): RangeFacetResult {\n\t\tconst counts =\n\t\t\tranges?.map((range) => {\n\t\t\t\tif (source.startsWith(\"variants.\")) {\n\t\t\t\t\tconst values: number[] = [];\n\t\t\t\t\tfor (const p of products) {\n\t\t\t\t\t\tfor (const v of getVariants(p)) {\n\t\t\t\t\t\t\tconst val = resolveVariantValue(v, source);\n\t\t\t\t\t\t\tif (val === undefined) {\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (range.match(val)) {\n\t\t\t\t\t\t\t\tvalues.push(val);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tconst numValues = values.length;\n\t\t\t\t\treturn {\n\t\t\t\t\t\ttype: \"double\",\n\t\t\t\t\t\tfrom: range.start || 0,\n\t\t\t\t\t\tfromStr: range.start !== null ? Number(range.start).toFixed(1) : \"\",\n\t\t\t\t\t\tto: range.stop || 0,\n\t\t\t\t\t\ttoStr: range.stop !== null ? Number(range.stop).toFixed(1) : \"\",\n\t\t\t\t\t\tcount: numValues,\n\t\t\t\t\t\t// totalCount: 0,\n\t\t\t\t\t\ttotal: values.reduce((a, b) => a + b, 0),\n\t\t\t\t\t\tmin: numValues > 0 ? Math.min(...values) : 0,\n\t\t\t\t\t\tmax: numValues > 0 ? Math.max(...values) : 0,\n\t\t\t\t\t\tmean: numValues > 0 ? mean(values) : 0,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\tthrow new Error(\"not supported\");\n\t\t\t}) || [];\n\t\tconst data: RangeFacetResult = {\n\t\t\ttype: \"range\",\n\t\t\t// @ts-expect-error\n\t\t\tdataType: \"number\",\n\t\t\tranges: counts,\n\t\t};\n\t\treturn data;\n\t}\n}\n\nconst mean = (arr: number[]) => {\n\tlet total = 0;\n\tfor (let i = 0; i < arr.length; i++) {\n\t\ttotal += arr[i];\n\t}\n\treturn total / arr.length;\n};\n","import type {\n\tInvalidInputError,\n\tProductDraft,\n\tProductProjection,\n\tQueryParam,\n} from \"@commercetools/platform-sdk\";\nimport type { Config } from \"#src/config.ts\";\nimport { CommercetoolsError } from \"#src/exceptions.ts\";\nimport { parseQueryExpression } from \"../lib/predicateParser.ts\";\nimport { applyPriceSelector } from \"../priceSelector.ts\";\nimport { ProductProjectionSearch } from \"../product-projection-search.ts\";\nimport type { GetParams, RepositoryContext } from \"./abstract.ts\";\nimport { AbstractResourceRepository } from \"./abstract.ts\";\n\nexport type ProductProjectionQueryParams = {\n\tstaged?: boolean;\n\tpriceCurrency?: string;\n\tpriceCountry?: string;\n\tpriceCustomerGroup?: string;\n\tpriceChannel?: string;\n\tlocaleProjection?: string;\n\tstoreProjection?: string;\n\texpand?: string | string[];\n\tsort?: string | string[];\n\tlimit?: number;\n\toffset?: number;\n\twithTotal?: boolean;\n\twhere?: string | string[];\n\t[key: string]: QueryParam;\n};\n\nexport class ProductProjectionRepository extends AbstractResourceRepository<\"product-projection\"> {\n\tprotected _searchService: ProductProjectionSearch;\n\n\tconstructor(config: Config) {\n\t\tsuper(\"product-projection\", config);\n\t\tthis._searchService = new ProductProjectionSearch(config);\n\t}\n\n\tcreate(context: RepositoryContext, draft: ProductDraft): ProductProjection {\n\t\tthrow new Error(\"No valid action\");\n\t}\n\n\tget(\n\t\tcontext: RepositoryContext,\n\t\tid: string,\n\t\tparams: GetParams = {},\n\t): ProductProjection | null {\n\t\tconst resource = this._storage.get(\n\t\t\tcontext.projectKey,\n\t\t\t\"product\",\n\t\t\tid,\n\t\t\tparams,\n\t\t);\n\t\tif (resource) {\n\t\t\treturn this._searchService.transform(resource, false, context.projectKey);\n\t\t}\n\t\treturn null;\n\t}\n\n\tquery(context: RepositoryContext, params: ProductProjectionQueryParams = {}) {\n\t\tlet resources = this._storage\n\t\t\t.all(context.projectKey, \"product\")\n\t\t\t.map((r) =>\n\t\t\t\tthis._searchService.transform(\n\t\t\t\t\tr,\n\t\t\t\t\tparams.staged ?? false,\n\t\t\t\t\tcontext.projectKey,\n\t\t\t\t),\n\t\t\t)\n\t\t\t.filter((p) => {\n\t\t\t\tif (!(params.staged ?? false)) {\n\t\t\t\t\treturn p.published;\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t});\n\n\t\t// Apply predicates\n\t\tif (params.where) {\n\t\t\tconst variableMap: Record<string, QueryParam> = {};\n\t\t\tfor (const [k, v] of Object.entries(params)) {\n\t\t\t\tif (k.startsWith(\"var.\")) {\n\t\t\t\t\tvariableMap[k.substring(4)] = v;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tconst filterFunc = parseQueryExpression(params.where);\n\t\t\t\tresources = resources.filter((resource) =>\n\t\t\t\t\tfilterFunc(resource, variableMap),\n\t\t\t\t);\n\t\t\t} catch (err) {\n\t\t\t\tthrow new CommercetoolsError<InvalidInputError>(\n\t\t\t\t\t{\n\t\t\t\t\t\tcode: \"InvalidInput\",\n\t\t\t\t\t\tmessage: (err as any).message,\n\t\t\t\t\t},\n\t\t\t\t\t400,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\t// We do this after the filtering, since the docs mention:\n\t\t// Only available when Price selection is used. Cannot be used in a Query\n\t\t// Predicate.\n\t\tapplyPriceSelector(\n\t\t\tresources,\n\t\t\t{\n\t\t\t\tcountry: params.priceCountry,\n\t\t\t\tchannel: params.priceChannel,\n\t\t\t\tcustomerGroup: params.priceCustomerGroup,\n\t\t\t\tcurrency: params.priceCurrency,\n\t\t\t},\n\t\t\ttrue,\n\t\t);\n\n\t\t// Expand the resources\n\t\tif (params.expand !== undefined) {\n\t\t\tresources = resources.map((resource) =>\n\t\t\t\tthis._storage.expand(context.projectKey, resource, params.expand),\n\t\t\t);\n\t\t}\n\n\t\t// Create a slice for the pagination. If we were working with large datasets\n\t\t// then we should have done this before transforming. But that isn't the\n\t\t// goal of this library. So lets keep it simple.\n\t\tconst totalResults = resources.length;\n\t\tconst offset = params.offset || 0;\n\t\tconst limit = params.limit || 20;\n\t\tconst results = resources.slice(offset, offset + limit);\n\n\t\treturn {\n\t\t\tcount: totalResults,\n\t\t\ttotal: results.length,\n\t\t\toffset: offset,\n\t\t\tlimit: limit,\n\t\t\tresults: results,\n\t\t};\n\t}\n\n\tsearch(context: RepositoryContext, query: ProductProjectionQueryParams) {\n\t\treturn this._searchService.search(context.projectKey, query);\n\t}\n}\n","import type {\n\tProductSelection,\n\tProductSelectionChangeNameAction,\n\tProductSelectionDraft,\n\tProductSelectionSetCustomTypeAction,\n\tProductSelectionUpdateAction,\n} from \"@commercetools/platform-sdk\";\nimport type { Config } from \"#src/config.ts\";\nimport { createCustomFields } from \"#src/repositories/helpers.ts\";\nimport { getBaseResourceProperties } from \"../helpers.ts\";\nimport type { Writable } from \"../types.ts\";\nimport type { RepositoryContext, UpdateHandlerInterface } from \"./abstract.ts\";\nimport {\n\tAbstractResourceRepository,\n\tAbstractUpdateHandler,\n} from \"./abstract.ts\";\n\nexport class ProductSelectionRepository extends AbstractResourceRepository<\"product-selection\"> {\n\tconstructor(config: Config) {\n\t\tsuper(\"product-selection\", config);\n\t\tthis.actions = new ProductSelectionUpdateHandler(this._storage);\n\t}\n\n\tcreate(\n\t\tcontext: RepositoryContext,\n\t\tdraft: ProductSelectionDraft,\n\t): ProductSelection {\n\t\tconst resource: ProductSelection = {\n\t\t\t...getBaseResourceProperties(),\n\t\t\tproductCount: 0,\n\t\t\tkey: draft.key,\n\t\t\tname: draft.name,\n\t\t\tmode: \"Individual\",\n\t\t};\n\t\treturn this.saveNew(context, resource);\n\t}\n}\n\nclass ProductSelectionUpdateHandler\n\textends AbstractUpdateHandler\n\timplements\n\t\tPartial<\n\t\t\tUpdateHandlerInterface<ProductSelection, ProductSelectionUpdateAction>\n\t\t>\n{\n\tchangeName(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<ProductSelection>,\n\t\t{ name }: ProductSelectionChangeNameAction,\n\t) {\n\t\tresource.name = name;\n\t}\n\n\tsetCustomType(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<ProductSelection>,\n\t\t{ type, fields }: ProductSelectionSetCustomTypeAction,\n\t) {\n\t\tif (type) {\n\t\t\tresource.custom = createCustomFields(\n\t\t\t\t{ type, fields },\n\t\t\t\tcontext.projectKey,\n\t\t\t\tthis._storage,\n\t\t\t);\n\t\t} else {\n\t\t\tresource.custom = undefined;\n\t\t}\n\t}\n}\n","import type {\n\tAttributeDefinition,\n\tAttributeDefinitionDraft,\n\tAttributeType,\n\tProductType,\n\tProductTypeAddAttributeDefinitionAction,\n\tProductTypeChangeAttributeOrderByNameAction,\n\tProductTypeChangeLabelAction,\n\tProductTypeChangeLocalizedEnumValueLabelAction,\n\tProductTypeDraft,\n\tProductTypeRemoveAttributeDefinitionAction,\n\tProductTypeRemoveEnumValuesAction,\n\tProductTypeUpdateAction,\n} from \"@commercetools/platform-sdk\";\nimport type { Config } from \"#src/config.ts\";\nimport { getBaseResourceProperties } from \"../helpers.ts\";\nimport type { Writable } from \"../types.ts\";\nimport type { RepositoryContext, UpdateHandlerInterface } from \"./abstract.ts\";\nimport {\n\tAbstractResourceRepository,\n\tAbstractUpdateHandler,\n} from \"./abstract.ts\";\n\nexport class ProductTypeRepository extends AbstractResourceRepository<\"product-type\"> {\n\tconstructor(config: Config) {\n\t\tsuper(\"product-type\", config);\n\t\tthis.actions = new ProductTypeUpdateHandler(config.storage);\n\t}\n\n\tcreate(context: RepositoryContext, draft: ProductTypeDraft): ProductType {\n\t\tconst resource: ProductType = {\n\t\t\t...getBaseResourceProperties(),\n\t\t\tkey: draft.key,\n\t\t\tname: draft.name,\n\t\t\tdescription: draft.description,\n\t\t\tattributes: (draft.attributes ?? []).map((a) =>\n\t\t\t\tattributeDefinitionFromAttributeDefinitionDraft(context, a),\n\t\t\t),\n\t\t};\n\n\t\treturn this.saveNew(context, resource);\n\t}\n}\n\nconst attributeDefinitionFromAttributeDefinitionDraft = (\n\t_context: RepositoryContext,\n\tdraft: AttributeDefinitionDraft,\n): AttributeDefinition => ({\n\t...draft,\n\tlevel: draft.level ?? \"Variant\",\n\tattributeConstraint: draft.attributeConstraint ?? \"None\",\n\tinputHint: draft.inputHint ?? \"SingleLine\",\n\tinputTip:\n\t\tdraft.inputTip && Object.keys(draft.inputTip).length > 0\n\t\t\t? draft.inputTip\n\t\t\t: undefined,\n\tisSearchable: draft.isSearchable ?? true,\n});\n\nclass ProductTypeUpdateHandler\n\textends AbstractUpdateHandler\n\timplements\n\t\tPartial<UpdateHandlerInterface<ProductType, ProductTypeUpdateAction>>\n{\n\taddAttributeDefinition(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<ProductType>,\n\t\t{ attribute }: ProductTypeAddAttributeDefinitionAction,\n\t) {\n\t\tresource.attributes?.push(\n\t\t\tattributeDefinitionFromAttributeDefinitionDraft(context, attribute),\n\t\t);\n\t}\n\n\tchangeAttributeOrderByName(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<ProductType>,\n\t\t{ attributeNames }: ProductTypeChangeAttributeOrderByNameAction,\n\t) {\n\t\tconst attrs = new Map(\n\t\t\tresource.attributes?.map((item) => [item.name, item]),\n\t\t);\n\t\tconst result: AttributeDefinition[] = [];\n\t\tlet current = resource.attributes;\n\n\t\tattributeNames.forEach((attrName) => {\n\t\t\tconst attr = attrs.get(attrName);\n\t\t\tif (attr === undefined) {\n\t\t\t\tthrow new Error(\"New attr\");\n\t\t\t}\n\t\t\tresult.push(attr);\n\n\t\t\t// Remove from current items\n\t\t\tcurrent = current?.filter((f) => f.name !== attrName);\n\t\t});\n\n\t\tresource.attributes = result;\n\t\t// Add attrs which were not specified in the order as last items. Not\n\t\t// sure if this follows commercetools\n\t\tif (current) {\n\t\t\tresource.attributes.push(...current);\n\t\t}\n\t}\n\n\tchangeLabel(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<ProductType>,\n\t\t{ attributeName, label }: ProductTypeChangeLabelAction,\n\t) {\n\t\tresource.attributes?.forEach((value) => {\n\t\t\tif (value.name === attributeName) {\n\t\t\t\tvalue.label = label;\n\t\t\t}\n\t\t});\n\t}\n\n\tchangeLocalizedEnumValueLabel(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<ProductType>,\n\t\t{ attributeName, newValue }: ProductTypeChangeLocalizedEnumValueLabelAction,\n\t) {\n\t\tconst updateAttributeType = (type: Writable<AttributeType>) => {\n\t\t\tswitch (type.name) {\n\t\t\t\tcase \"lenum\":\n\t\t\t\t\ttype.values.forEach((v) => {\n\t\t\t\t\t\tif (v.key === newValue.key) {\n\t\t\t\t\t\t\tv.label = newValue.label;\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t\treturn;\n\t\t\t\tcase \"set\":\n\t\t\t\t\tupdateAttributeType(type.elementType);\n\t\t\t\t\treturn;\n\t\t\t}\n\t\t};\n\n\t\tresource.attributes?.forEach((value) => {\n\t\t\tif (value.name === attributeName) {\n\t\t\t\tupdateAttributeType(value.type);\n\t\t\t}\n\t\t});\n\t}\n\n\tremoveAttributeDefinition(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<ProductType>,\n\t\t{ name }: ProductTypeRemoveAttributeDefinitionAction,\n\t) {\n\t\tresource.attributes = resource.attributes?.filter((f) => f.name !== name);\n\t}\n\n\tremoveEnumValues(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<ProductType>,\n\t\t{ attributeName, keys }: ProductTypeRemoveEnumValuesAction,\n\t) {\n\t\tresource.attributes?.forEach((attr) => {\n\t\t\tif (attr.name === attributeName) {\n\t\t\t\tif (attr.type.name === \"enum\") {\n\t\t\t\t\tattr.type.values = attr.type.values.filter(\n\t\t\t\t\t\t(v) => !keys.includes(v.key),\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tif (attr.type.name === \"set\") {\n\t\t\t\t\tif (attr.type.elementType.name === \"enum\") {\n\t\t\t\t\t\tattr.type.elementType.values = attr.type.elementType.values.filter(\n\t\t\t\t\t\t\t(v) => !keys.includes(v.key),\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t}\n}\n","import type {\n\tProject,\n\tProjectChangeBusinessUnitSearchStatusAction,\n\tProjectChangeBusinessUnitStatusOnCreationAction,\n\tProjectChangeCartsConfigurationAction,\n\tProjectChangeCountriesAction,\n\tProjectChangeCountryTaxRateFallbackEnabledAction,\n\tProjectChangeCurrenciesAction,\n\tProjectChangeCustomerSearchStatusAction,\n\tProjectChangeLanguagesAction,\n\tProjectChangeMessagesConfigurationAction,\n\tProjectChangeNameAction,\n\tProjectChangeOrderSearchStatusAction,\n\tProjectChangePriceRoundingModeAction,\n\tProjectChangeProductSearchIndexingEnabledAction,\n\tProjectChangeShoppingListsConfigurationAction,\n\tProjectChangeTaxRoundingModeAction,\n\tProjectSetExternalOAuthAction,\n\tProjectSetShippingRateInputTypeAction,\n\tProjectUpdateAction,\n} from \"@commercetools/platform-sdk\";\nimport type { ProjectSetBusinessUnitAssociateRoleOnCreationAction } from \"@commercetools/platform-sdk/dist/declarations/src/generated/models/project\";\nimport type { Config } from \"#src/config.ts\";\nimport { maskSecretValue } from \"../lib/masking.ts\";\nimport type { Writable } from \"../types.ts\";\nimport type { RepositoryContext, UpdateHandlerInterface } from \"./abstract.ts\";\nimport { AbstractRepository, AbstractUpdateHandler } from \"./abstract.ts\";\n\nexport class ProjectRepository extends AbstractRepository<Project> {\n\tconstructor(config: Config) {\n\t\tsuper(config);\n\t\tthis.actions = new ProjectUpdateHandler(config.storage);\n\t}\n\n\tget(context: RepositoryContext): Project | null {\n\t\tconst resource = this._storage.getProject(context.projectKey);\n\t\treturn this.postProcessResource(context, resource);\n\t}\n\n\tpostProcessResource(context: RepositoryContext, resource: Project): Project {\n\t\tif (resource) {\n\t\t\treturn maskSecretValue(resource, \"externalOAuth.authorizationHeader\");\n\t\t}\n\t\treturn resource;\n\t}\n\n\tsaveNew(context: RepositoryContext, resource: Writable<Project>) {\n\t\tresource.version = 1;\n\t\tthis._storage.saveProject(resource);\n\t}\n\n\tsaveUpdate(context: RepositoryContext, version: number, resource: Project) {\n\t\tthis._storage.saveProject(resource);\n\t}\n}\n\nclass ProjectUpdateHandler\n\textends AbstractUpdateHandler\n\timplements Partial<UpdateHandlerInterface<Project, ProjectUpdateAction>>\n{\n\tchangeCartsConfiguration(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Project>,\n\t\t{ cartsConfiguration }: ProjectChangeCartsConfigurationAction,\n\t) {\n\t\tresource.carts = cartsConfiguration || {\n\t\t\tcountryTaxRateFallbackEnabled: false,\n\t\t\tdeleteDaysAfterLastModification: 90,\n\t\t\tpriceRoundingMode: \"HalfEven\",\n\t\t\ttaxRoundingMode: \"HalfEven\",\n\t\t};\n\t}\n\n\tchangeShoppingListsConfiguration(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Project>,\n\t\t{\n\t\t\tshoppingListsConfiguration,\n\t\t}: ProjectChangeShoppingListsConfigurationAction,\n\t) {\n\t\tresource.shoppingLists = shoppingListsConfiguration || {\n\t\t\tdeleteDaysAfterLastModification: 90,\n\t\t};\n\t}\n\n\tchangeCountries(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Project>,\n\t\t{ countries }: ProjectChangeCountriesAction,\n\t) {\n\t\tresource.countries = countries;\n\t}\n\n\tchangeCountryTaxRateFallbackEnabled(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Project>,\n\t\t{\n\t\t\tcountryTaxRateFallbackEnabled,\n\t\t}: ProjectChangeCountryTaxRateFallbackEnabledAction,\n\t) {\n\t\tresource.carts.countryTaxRateFallbackEnabled =\n\t\t\tcountryTaxRateFallbackEnabled;\n\t}\n\n\tchangePriceRoundingMode(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Project>,\n\t\t{ priceRoundingMode }: ProjectChangePriceRoundingModeAction,\n\t) {\n\t\tresource.carts.priceRoundingMode = priceRoundingMode;\n\t}\n\n\tchangeTaxRoundingMode(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Project>,\n\t\t{ taxRoundingMode }: ProjectChangeTaxRoundingModeAction,\n\t) {\n\t\tresource.carts.taxRoundingMode = taxRoundingMode;\n\t}\n\n\tchangeCurrencies(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Project>,\n\t\t{ currencies }: ProjectChangeCurrenciesAction,\n\t) {\n\t\tresource.currencies = currencies;\n\t}\n\n\tchangeCustomerSearchStatus(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Project>,\n\t\t{ status }: ProjectChangeCustomerSearchStatusAction,\n\t) {\n\t\tif (!resource.searchIndexing?.customers) {\n\t\t\tthrow new Error(\"Invalid project state\");\n\t\t}\n\t\tresource.searchIndexing.customers.status = status;\n\t\tresource.searchIndexing.customers.lastModifiedAt = new Date().toISOString();\n\t}\n\n\tchangeBusinessUnitSearchStatus(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Project>,\n\t\t{ status }: ProjectChangeBusinessUnitSearchStatusAction,\n\t) {\n\t\tif (!resource.searchIndexing?.businessUnits) {\n\t\t\tthrow new Error(\"Invalid project state\");\n\t\t}\n\t\tresource.searchIndexing.businessUnits.status = status;\n\t\tresource.searchIndexing.businessUnits.lastModifiedAt =\n\t\t\tnew Date().toISOString();\n\t}\n\n\tchangeLanguages(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Project>,\n\t\t{ languages }: ProjectChangeLanguagesAction,\n\t) {\n\t\tresource.languages = languages;\n\t}\n\n\tchangeMessagesConfiguration(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Project>,\n\t\t{ messagesConfiguration }: ProjectChangeMessagesConfigurationAction,\n\t) {\n\t\tresource.messages.enabled = messagesConfiguration.enabled;\n\t\tresource.messages.deleteDaysAfterCreation =\n\t\t\tmessagesConfiguration.deleteDaysAfterCreation;\n\t}\n\n\tchangeMyBusinessUnitStatusOnCreation(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Project>,\n\t\t{ status }: ProjectChangeBusinessUnitStatusOnCreationAction,\n\t) {\n\t\tif (resource.businessUnits === undefined) {\n\t\t\tresource.businessUnits = {\n\t\t\t\tmyBusinessUnitStatusOnCreation: \"Inactive\",\n\t\t\t};\n\t\t}\n\n\t\tresource.businessUnits.myBusinessUnitStatusOnCreation = status;\n\t}\n\n\tchangeName(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Project>,\n\t\t{ name }: ProjectChangeNameAction,\n\t) {\n\t\tresource.name = name;\n\t}\n\n\tchangeOrderSearchStatus(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Project>,\n\t\t{ status }: ProjectChangeOrderSearchStatusAction,\n\t) {\n\t\tif (!resource.searchIndexing?.orders) {\n\t\t\tthrow new Error(\"Invalid project state\");\n\t\t}\n\t\tresource.searchIndexing.orders.status = status;\n\t\tresource.searchIndexing.orders.lastModifiedAt = new Date().toISOString();\n\t}\n\n\tchangeProductSearchIndexingEnabled(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Project>,\n\t\t{ enabled, mode }: ProjectChangeProductSearchIndexingEnabledAction,\n\t) {\n\t\tif (mode === \"ProductsSearch\") {\n\t\t\tif (!resource.searchIndexing?.productsSearch) {\n\t\t\t\tthrow new Error(\"Invalid project state\");\n\t\t\t}\n\t\t\tresource.searchIndexing.productsSearch.status = enabled\n\t\t\t\t? \"Activated\"\n\t\t\t\t: \"Deactivated\";\n\t\t\tresource.searchIndexing.productsSearch.lastModifiedAt =\n\t\t\t\tnew Date().toISOString();\n\t\t\treturn;\n\t\t}\n\n\t\tif (!resource.searchIndexing?.products) {\n\t\t\tthrow new Error(\"Invalid project state\");\n\t\t}\n\t\tresource.searchIndexing.products.status = enabled\n\t\t\t? \"Activated\"\n\t\t\t: \"Deactivated\";\n\t\tresource.searchIndexing.products.lastModifiedAt = new Date().toISOString();\n\t}\n\n\tsetExternalOAuth(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Project>,\n\t\t{ externalOAuth }: ProjectSetExternalOAuthAction,\n\t) {\n\t\tresource.externalOAuth = externalOAuth;\n\t}\n\n\tsetMyBusinessUnitAssociateRoleOnCreation(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Project>,\n\t\t{ associateRole }: ProjectSetBusinessUnitAssociateRoleOnCreationAction,\n\t) {\n\t\tif (resource.businessUnits === undefined) {\n\t\t\tresource.businessUnits = {\n\t\t\t\t//Default status, so we set it here also\n\t\t\t\tmyBusinessUnitStatusOnCreation: \"Inactive\",\n\t\t\t};\n\t\t}\n\n\t\tresource.businessUnits.myBusinessUnitAssociateRoleOnCreation = {\n\t\t\ttypeId: associateRole.typeId,\n\t\t\tkey: associateRole.key ?? \"unknown\",\n\t\t};\n\t}\n\n\tsetShippingRateInputType(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Project>,\n\t\t{ shippingRateInputType }: ProjectSetShippingRateInputTypeAction,\n\t) {\n\t\tresource.shippingRateInputType = shippingRateInputType;\n\t}\n}\n","import type {\n\tInvalidJsonInputError,\n\tQuote,\n\tQuoteSetCustomFieldAction,\n\tQuoteSetCustomTypeAction,\n\tQuoteTransitionStateAction,\n\tQuoteUpdateAction,\n\tStateReference,\n} from \"@commercetools/platform-sdk\";\nimport { CommercetoolsError } from \"#src/exceptions.ts\";\nimport type { Writable } from \"#src/types.ts\";\nimport type { RepositoryContext, UpdateHandlerInterface } from \"../abstract.ts\";\nimport { AbstractUpdateHandler } from \"../abstract.ts\";\nimport { getReferenceFromResourceIdentifier } from \"../helpers.ts\";\n\nexport class QuoteUpdateHandler\n\textends AbstractUpdateHandler\n\timplements Partial<UpdateHandlerInterface<Quote, QuoteUpdateAction>>\n{\n\tsetCustomField(\n\t\tcontext: RepositoryContext,\n\t\tresource: Quote,\n\t\t{ name, value }: QuoteSetCustomFieldAction,\n\t) {\n\t\tif (!resource.custom) {\n\t\t\tthrow new Error(\"Resource has no custom field\");\n\t\t}\n\t\tresource.custom.fields[name] = value;\n\t}\n\n\tsetCustomType(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Quote>,\n\t\t{ type, fields }: QuoteSetCustomTypeAction,\n\t) {\n\t\tif (!type) {\n\t\t\tresource.custom = undefined;\n\t\t} else {\n\t\t\tconst resolvedType = this._storage.getByResourceIdentifier(\n\t\t\t\tcontext.projectKey,\n\t\t\t\ttype,\n\t\t\t);\n\t\t\tif (!resolvedType) {\n\t\t\t\tthrow new Error(`Type ${type} not found`);\n\t\t\t}\n\n\t\t\tresource.custom = {\n\t\t\t\ttype: {\n\t\t\t\t\ttypeId: \"type\",\n\t\t\t\t\tid: resolvedType.id,\n\t\t\t\t},\n\t\t\t\tfields: fields || {},\n\t\t\t};\n\t\t}\n\t}\n\n\ttransitionState(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Quote>,\n\t\t{ state, force }: QuoteTransitionStateAction,\n\t) {\n\t\tlet stateReference: StateReference | undefined;\n\t\tif (state) {\n\t\t\tstateReference = getReferenceFromResourceIdentifier<StateReference>(\n\t\t\t\tstate,\n\t\t\t\tcontext.projectKey,\n\t\t\t\tthis._storage,\n\t\t\t);\n\t\t\tresource.state = stateReference;\n\t\t} else {\n\t\t\tthrow new CommercetoolsError<InvalidJsonInputError>(\n\t\t\t\t{\n\t\t\t\t\tcode: \"InvalidJsonInput\",\n\t\t\t\t\tmessage: \"Request body does not contain valid JSON.\",\n\t\t\t\t\tdetailedErrorMessage: \"actions -> state: Missing required value\",\n\t\t\t\t},\n\t\t\t\t400,\n\t\t\t);\n\t\t}\n\n\t\treturn resource;\n\t}\n}\n","import type { Quote, QuoteDraft } from \"@commercetools/platform-sdk\";\nimport type { Config } from \"#src/config.ts\";\nimport { getBaseResourceProperties } from \"#src/helpers.ts\";\nimport type { RepositoryContext } from \"../abstract.ts\";\nimport { AbstractResourceRepository } from \"../abstract.ts\";\nimport { QuoteUpdateHandler } from \"./actions.ts\";\n\nexport class QuoteRepository extends AbstractResourceRepository<\"quote\"> {\n\tconstructor(config: Config) {\n\t\tsuper(\"quote\", config);\n\t\tthis.actions = new QuoteUpdateHandler(config.storage);\n\t}\n\n\tcreate(context: RepositoryContext, draft: QuoteDraft): Quote {\n\t\tconst staged = this._storage.getByResourceIdentifier<\"staged-quote\">(\n\t\t\tcontext.projectKey,\n\t\t\tdraft.stagedQuote,\n\t\t);\n\n\t\tconst cart = this._storage.getByResourceIdentifier<\"cart\">(\n\t\t\tcontext.projectKey,\n\t\t\tstaged.quotationCart,\n\t\t);\n\n\t\tif (!cart.customerId) {\n\t\t\tthrow new Error(\"Cart does not have a customer\");\n\t\t}\n\n\t\tconst resource: Quote = {\n\t\t\t...getBaseResourceProperties(),\n\t\t\tquoteState: \"Accepted\",\n\t\t\tquoteRequest: staged.quoteRequest,\n\t\t\tlineItems: cart.lineItems,\n\t\t\tcustomLineItems: cart.customLineItems,\n\t\t\tcustomer: {\n\t\t\t\ttypeId: \"customer\",\n\t\t\t\tid: cart.customerId,\n\t\t\t},\n\t\t\tstagedQuote: {\n\t\t\t\ttypeId: \"staged-quote\",\n\t\t\t\tid: staged.id,\n\t\t\t},\n\t\t\tpriceRoundingMode: cart.priceRoundingMode,\n\t\t\ttotalPrice: cart.totalPrice,\n\t\t\ttaxedPrice: cart.taxedPrice,\n\t\t\ttaxMode: cart.taxMode,\n\t\t\ttaxRoundingMode: cart.taxRoundingMode,\n\t\t\ttaxCalculationMode: cart.taxCalculationMode,\n\t\t\tbillingAddress: cart.billingAddress,\n\t\t\tshippingAddress: cart.shippingAddress,\n\t\t};\n\n\t\treturn resource;\n\t}\n}\n","import type {\n\tInvalidJsonInputError,\n\tStagedQuote,\n\tStagedQuoteSetCustomFieldAction,\n\tStagedQuoteSetCustomTypeAction,\n\tStagedQuoteTransitionStateAction,\n\tStagedQuoteUpdateAction,\n\tStateReference,\n} from \"@commercetools/platform-sdk\";\nimport { CommercetoolsError } from \"#src/exceptions.ts\";\nimport type { Writable } from \"#src/types.ts\";\nimport type { RepositoryContext, UpdateHandlerInterface } from \"../abstract.ts\";\nimport { AbstractUpdateHandler } from \"../abstract.ts\";\nimport { getReferenceFromResourceIdentifier } from \"../helpers.ts\";\n\nexport class StagedQuoteUpdateHandler\n\textends AbstractUpdateHandler\n\timplements\n\t\tPartial<UpdateHandlerInterface<StagedQuote, StagedQuoteUpdateAction>>\n{\n\tsetCustomField(\n\t\tcontext: RepositoryContext,\n\t\tresource: StagedQuote,\n\t\t{ name, value }: StagedQuoteSetCustomFieldAction,\n\t) {\n\t\tif (!resource.custom) {\n\t\t\tthrow new Error(\"Resource has no custom field\");\n\t\t}\n\t\tresource.custom.fields[name] = value;\n\t}\n\n\tsetCustomType(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<StagedQuote>,\n\t\t{ type, fields }: StagedQuoteSetCustomTypeAction,\n\t) {\n\t\tif (!type) {\n\t\t\tresource.custom = undefined;\n\t\t} else {\n\t\t\tconst resolvedType = this._storage.getByResourceIdentifier(\n\t\t\t\tcontext.projectKey,\n\t\t\t\ttype,\n\t\t\t);\n\t\t\tif (!resolvedType) {\n\t\t\t\tthrow new Error(`Type ${type} not found`);\n\t\t\t}\n\n\t\t\tresource.custom = {\n\t\t\t\ttype: {\n\t\t\t\t\ttypeId: \"type\",\n\t\t\t\t\tid: resolvedType.id,\n\t\t\t\t},\n\t\t\t\tfields: fields || {},\n\t\t\t};\n\t\t}\n\t}\n\n\ttransitionState(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<StagedQuote>,\n\t\t{ state, force }: StagedQuoteTransitionStateAction,\n\t) {\n\t\tlet stateReference: StateReference | undefined;\n\t\tif (state) {\n\t\t\tstateReference = getReferenceFromResourceIdentifier<StateReference>(\n\t\t\t\tstate,\n\t\t\t\tcontext.projectKey,\n\t\t\t\tthis._storage,\n\t\t\t);\n\t\t\tresource.state = stateReference;\n\t\t} else {\n\t\t\tthrow new CommercetoolsError<InvalidJsonInputError>(\n\t\t\t\t{\n\t\t\t\t\tcode: \"InvalidJsonInput\",\n\t\t\t\t\tmessage: \"Request body does not contain valid JSON.\",\n\t\t\t\t\tdetailedErrorMessage: \"actions -> state: Missing required value\",\n\t\t\t\t},\n\t\t\t\t400,\n\t\t\t);\n\t\t}\n\n\t\treturn resource;\n\t}\n}\n","import type {\n\tStagedQuote,\n\tStagedQuoteDraft,\n} from \"@commercetools/platform-sdk\";\nimport type { Config } from \"#src/config.ts\";\nimport { getBaseResourceProperties } from \"#src/helpers.ts\";\nimport type { RepositoryContext } from \"../abstract.ts\";\nimport { AbstractResourceRepository } from \"../abstract.ts\";\nimport { StagedQuoteUpdateHandler } from \"./actions.ts\";\n\nexport class StagedQuoteRepository extends AbstractResourceRepository<\"staged-quote\"> {\n\tconstructor(config: Config) {\n\t\tsuper(\"staged-quote\", config);\n\t\tthis.actions = new StagedQuoteUpdateHandler(config.storage);\n\t}\n\n\tcreate(context: RepositoryContext, draft: StagedQuoteDraft): StagedQuote {\n\t\tconst quoteRequest = this._storage.getByResourceIdentifier<\"quote-request\">(\n\t\t\tcontext.projectKey,\n\t\t\tdraft.quoteRequest,\n\t\t);\n\n\t\tif (!quoteRequest.cart) {\n\t\t\tthrow new Error(\"Cannot find quote request\");\n\t\t}\n\n\t\tconst cart = this._storage.getByResourceIdentifier<\"cart\">(\n\t\t\tcontext.projectKey,\n\t\t\tquoteRequest.cart,\n\t\t);\n\n\t\tconst resource: StagedQuote = {\n\t\t\t...getBaseResourceProperties(),\n\t\t\tstagedQuoteState: \"InProgress\",\n\t\t\tquoteRequest: {\n\t\t\t\ttypeId: \"quote-request\",\n\t\t\t\tid: quoteRequest.id,\n\t\t\t},\n\t\t\tquotationCart: {\n\t\t\t\ttypeId: \"cart\",\n\t\t\t\tid: cart.id,\n\t\t\t},\n\t\t};\n\n\t\treturn resource;\n\t}\n}\n","import type {\n\tRecurrencePolicy,\n\tRecurrencePolicySetDescriptionAction,\n\tRecurrencePolicySetKeyAction,\n\tRecurrencePolicySetNameAction,\n\tRecurrencePolicySetScheduleAction,\n\tRecurrencePolicyUpdateAction,\n} from \"@commercetools/platform-sdk\";\nimport type { Writable } from \"#src/types.ts\";\nimport type { UpdateHandlerInterface } from \"../abstract.ts\";\nimport { AbstractUpdateHandler, type RepositoryContext } from \"../abstract.ts\";\n\nexport class RecurrencePolicyUpdateHandler\n\textends AbstractUpdateHandler\n\timplements\n\t\tPartial<\n\t\t\tUpdateHandlerInterface<RecurrencePolicy, RecurrencePolicyUpdateAction>\n\t\t>\n{\n\tsetKey(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<RecurrencePolicy>,\n\t\t{ key }: RecurrencePolicySetKeyAction,\n\t) {\n\t\tif (key) {\n\t\t\tresource.key = key;\n\t\t}\n\t}\n\n\tsetDescription(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<RecurrencePolicy>,\n\t\t{ description }: RecurrencePolicySetDescriptionAction,\n\t) {\n\t\tresource.description = description;\n\t}\n\n\tsetName(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<RecurrencePolicy>,\n\t\t{ name }: RecurrencePolicySetNameAction,\n\t) {\n\t\tresource.name = name;\n\t}\n\n\tsetSchedule(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<RecurrencePolicy>,\n\t\t{ schedule }: RecurrencePolicySetScheduleAction,\n\t) {\n\t\tresource.schedule = schedule;\n\t}\n}\n","import type {\n\tRecurrencePolicy,\n\tRecurrencePolicyDraft,\n} from \"@commercetools/platform-sdk\";\nimport type { Config } from \"#src/config.ts\";\nimport { getBaseResourceProperties } from \"#src/helpers.ts\";\nimport {\n\tAbstractResourceRepository,\n\ttype RepositoryContext,\n} from \"../abstract.ts\";\nimport { RecurrencePolicyUpdateHandler } from \"./actions.ts\";\n\nexport class RecurrencePolicyRepository extends AbstractResourceRepository<\"recurrence-policy\"> {\n\tconstructor(config: Config) {\n\t\tsuper(\"recurrence-policy\", config);\n\t\tthis.actions = new RecurrencePolicyUpdateHandler(config.storage);\n\t}\n\n\tcreate(\n\t\tcontext: RepositoryContext,\n\t\tdraft: RecurrencePolicyDraft,\n\t): RecurrencePolicy {\n\t\tconst resource: RecurrencePolicy = {\n\t\t\t...getBaseResourceProperties(),\n\t\t\tkey: draft.key,\n\t\t\tname: draft.name,\n\t\t\tdescription: draft.description,\n\t\t\tschedule: draft.schedule,\n\t\t};\n\t\treturn this.saveNew(context, resource);\n\t}\n}\n","import type {\n\tRecurringOrder,\n\tRecurringOrderSetCustomFieldAction,\n\tRecurringOrderSetCustomTypeAction,\n\tRecurringOrderSetExpiresAtAction,\n\tRecurringOrderSetKeyAction,\n\tRecurringOrderSetOrderSkipConfigurationAction,\n\tRecurringOrderSetScheduleAction,\n\tRecurringOrderSetStartsAtAction,\n\tRecurringOrderSetStateAction,\n\tRecurringOrderTransitionStateAction,\n\tRecurringOrderUpdateAction,\n} from \"@commercetools/platform-sdk\";\nimport type { Writable } from \"#src/types.ts\";\nimport type { UpdateHandlerInterface } from \"../abstract.ts\";\nimport { AbstractUpdateHandler, type RepositoryContext } from \"../abstract.ts\";\n\nexport class RecurringOrderUpdateHandler\n\textends AbstractUpdateHandler\n\timplements\n\t\tPartial<UpdateHandlerInterface<RecurringOrder, RecurringOrderUpdateAction>>\n{\n\tsetCustomField(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<RecurringOrder>,\n\t\t{ name, value }: RecurringOrderSetCustomFieldAction,\n\t) {\n\t\tif (!resource.custom) {\n\t\t\tthrow new Error(\"Resource has no custom field\");\n\t\t}\n\t\tif (value === null) {\n\t\t\tdelete resource.custom.fields[name];\n\t\t} else {\n\t\t\tresource.custom.fields[name] = value;\n\t\t}\n\t}\n\n\tsetCustomType(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<RecurringOrder>,\n\t\t{ type, fields }: RecurringOrderSetCustomTypeAction,\n\t) {\n\t\tif (!type) {\n\t\t\tresource.custom = undefined;\n\t\t} else {\n\t\t\tconst resolvedType = this._storage.getByResourceIdentifier(\n\t\t\t\tcontext.projectKey,\n\t\t\t\ttype,\n\t\t\t);\n\t\t\tif (!resolvedType) {\n\t\t\t\tthrow new Error(`Type ${type} not found`);\n\t\t\t}\n\n\t\t\tresource.custom = {\n\t\t\t\ttype: {\n\t\t\t\t\ttypeId: \"type\",\n\t\t\t\t\tid: resolvedType.id,\n\t\t\t\t},\n\t\t\t\tfields: fields || {},\n\t\t\t};\n\t\t}\n\t}\n\n\tsetExpiresAt(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<RecurringOrder>,\n\t\t{ expiresAt }: RecurringOrderSetExpiresAtAction,\n\t) {\n\t\tresource.expiresAt = expiresAt;\n\t}\n\n\tsetKey(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<RecurringOrder>,\n\t\t{ key }: RecurringOrderSetKeyAction,\n\t) {\n\t\tresource.key = key;\n\t}\n\n\tsetOrderSkipConfiguration(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<RecurringOrder>,\n\t\t{\n\t\t\tskipConfiguration,\n\t\t\tupdatedExpiresAt,\n\t\t}: RecurringOrderSetOrderSkipConfigurationAction,\n\t) {\n\t\tif (skipConfiguration) {\n\t\t\tresource.skipConfiguration = {\n\t\t\t\ttype: skipConfiguration.type,\n\t\t\t\ttotalToSkip: skipConfiguration.totalToSkip,\n\t\t\t\tskipped: 0,\n\t\t\t\tlastSkippedAt: undefined,\n\t\t\t};\n\t\t} else {\n\t\t\tresource.skipConfiguration = undefined;\n\t\t}\n\t\tif (updatedExpiresAt !== undefined) {\n\t\t\tresource.expiresAt = updatedExpiresAt;\n\t\t}\n\t}\n\n\tsetSchedule(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<RecurringOrder>,\n\t\t{ recurrencePolicy }: RecurringOrderSetScheduleAction,\n\t) {\n\t\tresource.schedule = {\n\t\t\t...resource.schedule,\n\t\t\t...recurrencePolicy,\n\t\t};\n\t}\n\n\tsetStartsAt(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<RecurringOrder>,\n\t\t{ startsAt }: RecurringOrderSetStartsAtAction,\n\t) {\n\t\tresource.startsAt = startsAt;\n\t}\n\n\tsetRecurringOrderState(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<RecurringOrder>,\n\t\t{ recurringOrderState }: RecurringOrderSetStateAction,\n\t) {\n\t\t// Map the state draft to the actual state\n\t\tswitch (recurringOrderState.type) {\n\t\t\tcase \"active\":\n\t\t\t\tresource.recurringOrderState = \"Active\";\n\t\t\t\tif (recurringOrderState.resumesAt) {\n\t\t\t\t\tresource.resumesAt = recurringOrderState.resumesAt;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase \"canceled\":\n\t\t\t\tresource.recurringOrderState = \"Canceled\";\n\t\t\t\tbreak;\n\t\t\tcase \"expired\":\n\t\t\t\tresource.recurringOrderState = \"Expired\";\n\t\t\t\tbreak;\n\t\t\tcase \"paused\":\n\t\t\t\tresource.recurringOrderState = \"Paused\";\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\ttransitionState(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<RecurringOrder>,\n\t\t{ state, force }: RecurringOrderTransitionStateAction,\n\t) {\n\t\tresource.state = {\n\t\t\ttypeId: \"state\",\n\t\t\tid: state.id!,\n\t\t};\n\t}\n}\n","import assert from \"node:assert\";\nimport type {\n\tRecurringOrder,\n\tRecurringOrderDraft,\n} from \"@commercetools/platform-sdk\";\nimport type { Config } from \"#src/config.ts\";\nimport { getBaseResourceProperties } from \"#src/helpers.ts\";\nimport {\n\tAbstractResourceRepository,\n\ttype RepositoryContext,\n} from \"../abstract.ts\";\nimport { OrderRepository } from \"../order/index.ts\";\nimport { RecurringOrderUpdateHandler } from \"./actions.ts\";\n\nexport class RecurringOrderRepository extends AbstractResourceRepository<\"recurring-order\"> {\n\tconstructor(config: Config) {\n\t\tsuper(\"recurring-order\", config);\n\t\tthis.actions = new RecurringOrderUpdateHandler(config.storage);\n\t}\n\n\tcreate(\n\t\tcontext: RepositoryContext,\n\t\tdraft: RecurringOrderDraft,\n\t): RecurringOrder {\n\t\tassert(draft.cart, \"draft.cart is missing\");\n\n\t\tconst orderRepo = new OrderRepository(this.config);\n\n\t\tconst initialOrder = orderRepo.createFromCart(context, {\n\t\t\tid: draft.cart.id!,\n\t\t\ttypeId: \"cart\",\n\t\t});\n\n\t\tconst resource: RecurringOrder = {\n\t\t\t...getBaseResourceProperties(),\n\t\t\tkey: draft.key,\n\t\t\tcart: {\n\t\t\t\ttypeId: \"cart\",\n\t\t\t\tid: draft.cart.id!,\n\t\t\t},\n\t\t\toriginOrder: {\n\t\t\t\ttypeId: \"order\",\n\t\t\t\tid: initialOrder.id,\n\t\t\t},\n\t\t\tstartsAt: draft.startsAt,\n\t\t\texpiresAt: draft.expiresAt,\n\t\t\trecurringOrderState: \"Active\",\n\t\t\tschedule: { type: \"standard\", intervalUnit: \"month\", value: 1 },\n\t\t};\n\t\treturn this.saveNew(context, resource);\n\t}\n}\n","import type {\n\tChannelReference,\n\tCustomerReference,\n\tProductReference,\n\tReview,\n\tReviewDraft,\n\tReviewSetAuthorNameAction,\n\tReviewSetCustomerAction,\n\tReviewSetCustomFieldAction,\n\tReviewSetCustomTypeAction,\n\tReviewSetKeyAction,\n\tReviewSetLocaleAction,\n\tReviewSetRatingAction,\n\tReviewSetTargetAction,\n\tReviewSetTextAction,\n\tReviewSetTitleAction,\n\tReviewTransitionStateAction,\n\tReviewUpdateAction,\n\tStateReference,\n} from \"@commercetools/platform-sdk\";\nimport type { Config } from \"#src/config.ts\";\nimport { getBaseResourceProperties } from \"../helpers.ts\";\nimport type { Writable } from \"../types.ts\";\nimport type { RepositoryContext, UpdateHandlerInterface } from \"./abstract.ts\";\nimport {\n\tAbstractResourceRepository,\n\tAbstractUpdateHandler,\n} from \"./abstract.ts\";\nimport {\n\tcreateCustomFields,\n\tgetReferenceFromResourceIdentifier,\n} from \"./helpers.ts\";\n\nexport class ReviewRepository extends AbstractResourceRepository<\"review\"> {\n\tconstructor(config: Config) {\n\t\tsuper(\"review\", config);\n\t\tthis.actions = new ReviewUpdateHandler(config.storage);\n\t}\n\n\tcreate(context: RepositoryContext, draft: ReviewDraft): Review {\n\t\tif (!draft.target) throw new Error(\"Missing target\");\n\t\tconst resource: Review = {\n\t\t\t...getBaseResourceProperties(),\n\t\t\tkey: draft.key,\n\t\t\tlocale: draft.locale,\n\t\t\tauthorName: draft.authorName,\n\t\t\ttitle: draft.title,\n\t\t\ttext: draft.text,\n\t\t\trating: draft.rating,\n\t\t\tuniquenessValue: draft.uniquenessValue,\n\t\t\tstate: draft.state\n\t\t\t\t? getReferenceFromResourceIdentifier<StateReference>(\n\t\t\t\t\t\tdraft.state,\n\t\t\t\t\t\tcontext.projectKey,\n\t\t\t\t\t\tthis._storage,\n\t\t\t\t\t)\n\t\t\t\t: undefined,\n\t\t\ttarget: draft.target\n\t\t\t\t? getReferenceFromResourceIdentifier<\n\t\t\t\t\t\tProductReference | ChannelReference\n\t\t\t\t\t>(draft.target, context.projectKey, this._storage)\n\t\t\t\t: undefined,\n\t\t\tincludedInStatistics: true,\n\t\t\tcustom: createCustomFields(\n\t\t\t\tdraft.custom,\n\t\t\t\tcontext.projectKey,\n\t\t\t\tthis._storage,\n\t\t\t),\n\t\t};\n\t\treturn this.saveNew(context, resource);\n\t}\n}\n\nclass ReviewUpdateHandler\n\textends AbstractUpdateHandler\n\timplements UpdateHandlerInterface<Review, ReviewUpdateAction>\n{\n\tsetAuthorName(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Review>,\n\t\t{ authorName }: ReviewSetAuthorNameAction,\n\t) {\n\t\tresource.authorName = authorName;\n\t}\n\n\tsetCustomField(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Review>,\n\t\t{ name, value }: ReviewSetCustomFieldAction,\n\t) {\n\t\tif (!resource.custom) {\n\t\t\tthrow new Error(\"Resource has no custom field\");\n\t\t}\n\t\tresource.custom.fields[name] = value;\n\t}\n\n\tsetCustomType(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Review>,\n\t\t{ type, fields }: ReviewSetCustomTypeAction,\n\t) {\n\t\tif (!type) {\n\t\t\tresource.custom = undefined;\n\t\t} else {\n\t\t\tconst resolvedType = this._storage.getByResourceIdentifier(\n\t\t\t\tcontext.projectKey,\n\t\t\t\ttype,\n\t\t\t);\n\t\t\tif (!resolvedType) {\n\t\t\t\tthrow new Error(`Type ${type} not found`);\n\t\t\t}\n\n\t\t\tresource.custom = {\n\t\t\t\ttype: {\n\t\t\t\t\ttypeId: \"type\",\n\t\t\t\t\tid: resolvedType.id,\n\t\t\t\t},\n\t\t\t\tfields: fields ?? {},\n\t\t\t};\n\t\t}\n\t}\n\n\tsetCustomer(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Review>,\n\t\t{ customer }: ReviewSetCustomerAction,\n\t) {\n\t\tresource.customer = customer\n\t\t\t? getReferenceFromResourceIdentifier<CustomerReference>(\n\t\t\t\t\tcustomer,\n\t\t\t\t\tcontext.projectKey,\n\t\t\t\t\tthis._storage,\n\t\t\t\t)\n\t\t\t: undefined;\n\t}\n\n\tsetKey(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Review>,\n\t\t{ key }: ReviewSetKeyAction,\n\t) {\n\t\tresource.key = key;\n\t}\n\n\tsetLocale(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Review>,\n\t\t{ locale }: ReviewSetLocaleAction,\n\t) {\n\t\tresource.locale = locale;\n\t}\n\n\tsetRating(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Review>,\n\t\t{ rating }: ReviewSetRatingAction,\n\t) {\n\t\tresource.rating = rating;\n\t}\n\n\tsetTarget(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Review>,\n\t\t{ target }: ReviewSetTargetAction,\n\t) {\n\t\tresource.target = getReferenceFromResourceIdentifier<\n\t\t\tProductReference | ChannelReference\n\t\t>(target, context.projectKey, this._storage);\n\t}\n\n\tsetText(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Review>,\n\t\t{ text }: ReviewSetTextAction,\n\t) {\n\t\tresource.text = text;\n\t}\n\n\tsetTitle(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Review>,\n\t\t{ title }: ReviewSetTitleAction,\n\t) {\n\t\tresource.title = title;\n\t}\n\n\ttransitionState(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Review>,\n\t\t{ state }: ReviewTransitionStateAction,\n\t) {\n\t\tresource.state = getReferenceFromResourceIdentifier<StateReference>(\n\t\t\tstate,\n\t\t\tcontext.projectKey,\n\t\t\tthis._storage,\n\t\t);\n\t}\n}\n","import type {\n\tShippingRate,\n\tShippingRateDraft,\n} from \"@commercetools/platform-sdk\";\nimport { createTypedMoney } from \"../helpers.ts\";\n\nexport const transformShippingRate = (\n\trate: ShippingRateDraft,\n): ShippingRate => ({\n\tprice: createTypedMoney(rate.price),\n\tfreeAbove: rate.freeAbove && createTypedMoney(rate.freeAbove),\n\ttiers: rate.tiers || [],\n});\n","import { isDeepStrictEqual } from \"node:util\";\nimport type {\n\tShippingMethod,\n\tShippingMethodAddShippingRateAction,\n\tShippingMethodAddZoneAction,\n\tShippingMethodChangeActiveAction,\n\tShippingMethodChangeIsDefaultAction,\n\tShippingMethodChangeNameAction,\n\tShippingMethodChangeTaxCategoryAction,\n\tShippingMethodRemoveShippingRateAction,\n\tShippingMethodRemoveZoneAction,\n\tShippingMethodSetCustomFieldAction,\n\tShippingMethodSetCustomTypeAction,\n\tShippingMethodSetDescriptionAction,\n\tShippingMethodSetKeyAction,\n\tShippingMethodSetLocalizedDescriptionAction,\n\tShippingMethodSetLocalizedNameAction,\n\tShippingMethodSetPredicateAction,\n\tShippingMethodUpdateAction,\n\tZoneReference,\n} from \"@commercetools/platform-sdk\";\nimport type { Writable } from \"#src/types.ts\";\nimport type { RepositoryContext, UpdateHandlerInterface } from \"../abstract.ts\";\nimport { AbstractUpdateHandler } from \"../abstract.ts\";\nimport {\n\tcreateCustomFields,\n\tgetReferenceFromResourceIdentifier,\n} from \"../helpers.ts\";\nimport { transformShippingRate } from \"./helpers.ts\";\n\nexport class ShippingMethodUpdateHandler\n\textends AbstractUpdateHandler\n\timplements UpdateHandlerInterface<ShippingMethod, ShippingMethodUpdateAction>\n{\n\tchangeTaxCategory: (\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<ShippingMethod>,\n\t\taction: ShippingMethodChangeTaxCategoryAction,\n\t) => void;\n\n\taddShippingRate(\n\t\t_context: RepositoryContext,\n\t\tresource: Writable<ShippingMethod>,\n\t\t{ shippingRate, zone }: ShippingMethodAddShippingRateAction,\n\t) {\n\t\tconst rate = transformShippingRate(shippingRate);\n\n\t\tresource.zoneRates.forEach((zoneRate) => {\n\t\t\tif (zoneRate.zone.id === zone.id) {\n\t\t\t\tzoneRate.shippingRates.push(rate);\n\t\t\t\treturn;\n\t\t\t}\n\t\t});\n\t\tresource.zoneRates.push({\n\t\t\tzone: {\n\t\t\t\ttypeId: \"zone\",\n\t\t\t\tid: zone.id!,\n\t\t\t},\n\t\t\tshippingRates: [rate],\n\t\t});\n\t}\n\n\taddZone(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<ShippingMethod>,\n\t\t{ zone }: ShippingMethodAddZoneAction,\n\t) {\n\t\tconst zoneReference = getReferenceFromResourceIdentifier<ZoneReference>(\n\t\t\tzone,\n\t\t\tcontext.projectKey,\n\t\t\tthis._storage,\n\t\t);\n\n\t\tif (resource.zoneRates === undefined) {\n\t\t\tresource.zoneRates = [];\n\t\t}\n\n\t\tresource.zoneRates.push({\n\t\t\tzone: zoneReference,\n\t\t\tshippingRates: [],\n\t\t});\n\t}\n\n\tchangeActive(\n\t\t_context: RepositoryContext,\n\t\tresource: Writable<ShippingMethod>,\n\t\t{ active }: ShippingMethodChangeActiveAction,\n\t) {\n\t\tresource.active = active;\n\t}\n\n\tchangeIsDefault(\n\t\t_context: RepositoryContext,\n\t\tresource: Writable<ShippingMethod>,\n\t\t{ isDefault }: ShippingMethodChangeIsDefaultAction,\n\t) {\n\t\tresource.isDefault = isDefault;\n\t}\n\n\tchangeName(\n\t\t_context: RepositoryContext,\n\t\tresource: Writable<ShippingMethod>,\n\t\t{ name }: ShippingMethodChangeNameAction,\n\t) {\n\t\tresource.name = name;\n\t}\n\n\tremoveShippingRate(\n\t\t_context: RepositoryContext,\n\t\tresource: Writable<ShippingMethod>,\n\t\t{ shippingRate, zone }: ShippingMethodRemoveShippingRateAction,\n\t) {\n\t\tconst rate = transformShippingRate(shippingRate);\n\n\t\tresource.zoneRates.forEach((zoneRate) => {\n\t\t\tif (zoneRate.zone.id === zone.id) {\n\t\t\t\tzoneRate.shippingRates = zoneRate.shippingRates.filter(\n\t\t\t\t\t(otherRate) => !isDeepStrictEqual(rate, otherRate),\n\t\t\t\t);\n\t\t\t}\n\t\t});\n\t}\n\n\tremoveZone(\n\t\t_context: RepositoryContext,\n\t\tresource: Writable<ShippingMethod>,\n\t\t{ zone }: ShippingMethodRemoveZoneAction,\n\t) {\n\t\tresource.zoneRates = resource.zoneRates.filter(\n\t\t\t(zoneRate) => zoneRate.zone.id !== zone.id,\n\t\t);\n\t}\n\n\tsetCustomField(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<ShippingMethod>,\n\t\t{ name, value }: ShippingMethodSetCustomFieldAction,\n\t) {\n\t\tif (!resource.custom) {\n\t\t\treturn;\n\t\t}\n\t\tif (value === null) {\n\t\t\tdelete resource.custom.fields[name];\n\t\t} else {\n\t\t\tresource.custom.fields[name] = value;\n\t\t}\n\t}\n\n\tsetCustomType(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<ShippingMethod>,\n\t\t{ type, fields }: ShippingMethodSetCustomTypeAction,\n\t) {\n\t\tif (type) {\n\t\t\tresource.custom = createCustomFields(\n\t\t\t\t{ type, fields },\n\t\t\t\tcontext.projectKey,\n\t\t\t\tthis._storage,\n\t\t\t);\n\t\t} else {\n\t\t\tresource.custom = undefined;\n\t\t}\n\t}\n\n\tsetDescription(\n\t\t_context: RepositoryContext,\n\t\tresource: Writable<ShippingMethod>,\n\t\t{ description }: ShippingMethodSetDescriptionAction,\n\t) {\n\t\tresource.description = description;\n\t}\n\n\tsetKey(\n\t\t_context: RepositoryContext,\n\t\tresource: Writable<ShippingMethod>,\n\t\t{ key }: ShippingMethodSetKeyAction,\n\t) {\n\t\tresource.key = key;\n\t}\n\n\tsetLocalizedDescription(\n\t\t_context: RepositoryContext,\n\t\tresource: Writable<ShippingMethod>,\n\t\t{ localizedDescription }: ShippingMethodSetLocalizedDescriptionAction,\n\t) {\n\t\tresource.localizedDescription = localizedDescription;\n\t}\n\n\tsetLocalizedName(\n\t\t_context: RepositoryContext,\n\t\tresource: Writable<ShippingMethod>,\n\t\t{ localizedName }: ShippingMethodSetLocalizedNameAction,\n\t) {\n\t\tresource.localizedName = localizedName;\n\t}\n\n\tsetPredicate(\n\t\t_context: RepositoryContext,\n\t\tresource: Writable<ShippingMethod>,\n\t\t{ predicate }: ShippingMethodSetPredicateAction,\n\t) {\n\t\tresource.predicate = predicate;\n\t}\n}\n","import type {\n\tShippingMethod,\n\tShippingMethodDraft,\n\tZoneRate,\n\tZoneRateDraft,\n\tZoneReference,\n} from \"@commercetools/platform-sdk\";\nimport type { Config } from \"#src/config.ts\";\nimport { getBaseResourceProperties } from \"../../helpers.ts\";\nimport { getShippingMethodsMatchingCart } from \"../../shipping.ts\";\nimport type { GetParams, RepositoryContext } from \"../abstract.ts\";\nimport { AbstractResourceRepository } from \"../abstract.ts\";\nimport {\n\tcreateCustomFields,\n\tgetReferenceFromResourceIdentifier,\n} from \"../helpers.ts\";\nimport { ShippingMethodUpdateHandler } from \"./actions.ts\";\nimport { transformShippingRate } from \"./helpers.ts\";\n\nexport class ShippingMethodRepository extends AbstractResourceRepository<\"shipping-method\"> {\n\tconstructor(config: Config) {\n\t\tsuper(\"shipping-method\", config);\n\t\tthis.actions = new ShippingMethodUpdateHandler(config.storage);\n\t}\n\n\tcreate(\n\t\tcontext: RepositoryContext,\n\t\tdraft: ShippingMethodDraft,\n\t): ShippingMethod {\n\t\tconst resource: ShippingMethod = {\n\t\t\t...getBaseResourceProperties(),\n\t\t\t...draft,\n\t\t\tactive: draft.active ?? true,\n\t\t\ttaxCategory: getReferenceFromResourceIdentifier(\n\t\t\t\tdraft.taxCategory,\n\t\t\t\tcontext.projectKey,\n\t\t\t\tthis._storage,\n\t\t\t),\n\t\t\tzoneRates: draft.zoneRates?.map((z) =>\n\t\t\t\tthis._transformZoneRateDraft(context, z),\n\t\t\t),\n\t\t\tcustom: createCustomFields(\n\t\t\t\tdraft.custom,\n\t\t\t\tcontext.projectKey,\n\t\t\t\tthis._storage,\n\t\t\t),\n\t\t};\n\t\treturn this.saveNew(context, resource);\n\t}\n\n\t/*\n\t * Retrieves all the ShippingMethods that can ship to the shipping address of\n\t * the given Cart. Each ShippingMethod contains exactly one ShippingRate with\n\t * the flag isMatching set to true. This ShippingRate is used when the\n\t * ShippingMethod is added to the Cart.\n\t */\n\tpublic matchingCart(\n\t\tcontext: RepositoryContext,\n\t\tcartId: string,\n\t\tparams: GetParams = {},\n\t) {\n\t\tconst cart = this._storage.get(context.projectKey, \"cart\", cartId);\n\t\tif (!cart) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\treturn getShippingMethodsMatchingCart(context, this._storage, cart, params);\n\t}\n\n\tprivate _transformZoneRateDraft(\n\t\tcontext: RepositoryContext,\n\t\tdraft: ZoneRateDraft,\n\t): ZoneRate {\n\t\treturn {\n\t\t\t...draft,\n\t\t\tzone: getReferenceFromResourceIdentifier<ZoneReference>(\n\t\t\t\tdraft.zone,\n\t\t\t\tcontext.projectKey,\n\t\t\t\tthis._storage,\n\t\t\t),\n\t\t\tshippingRates: draft.shippingRates?.map(transformShippingRate),\n\t\t};\n\t}\n}\n","import type {\n\tGeneralError,\n\tProduct,\n\tProductPagedQueryResponse,\n\tShoppingList,\n\tShoppingListAddLineItemAction,\n\tShoppingListChangeLineItemQuantityAction,\n\tShoppingListChangeNameAction,\n\tShoppingListLineItem,\n\tShoppingListRemoveLineItemAction,\n\tShoppingListSetAnonymousIdAction,\n\tShoppingListSetCustomerAction,\n\tShoppingListSetCustomFieldAction,\n\tShoppingListSetCustomTypeAction,\n\tShoppingListSetDeleteDaysAfterLastModificationAction,\n\tShoppingListSetDescriptionAction,\n\tShoppingListSetKeyAction,\n\tShoppingListSetSlugAction,\n\tShoppingListSetStoreAction,\n\tShoppingListUpdateAction,\n} from \"@commercetools/platform-sdk\";\nimport { v4 as uuidv4 } from \"uuid\";\nimport { CommercetoolsError } from \"#src/exceptions.ts\";\nimport type { Writable } from \"../../types.ts\";\nimport type { RepositoryContext, UpdateHandlerInterface } from \"../abstract.ts\";\nimport { AbstractUpdateHandler } from \"../abstract.ts\";\n\nexport class ShoppingListUpdateHandler\n\textends AbstractUpdateHandler\n\timplements\n\t\tPartial<UpdateHandlerInterface<ShoppingList, ShoppingListUpdateAction>>\n{\n\taddLineItem(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<ShoppingList>,\n\t\t{\n\t\t\tproductId,\n\t\t\tvariantId,\n\t\t\tsku,\n\t\t\tquantity = 1,\n\t\t\taddedAt,\n\t\t\tkey,\n\t\t}: ShoppingListAddLineItemAction,\n\t) {\n\t\tlet product: Product | null = null;\n\n\t\tif (productId) {\n\t\t\t// Fetch product and variant by ID\n\t\t\tproduct = this._storage.get(context.projectKey, \"product\", productId, {});\n\t\t} else if (sku) {\n\t\t\t// Fetch product and variant by SKU\n\t\t\tconst items = this._storage.query(context.projectKey, \"product\", {\n\t\t\t\twhere: [\n\t\t\t\t\t`masterData(current(masterVariant(sku=\"${sku}\"))) or masterData(current(variants(sku=\"${sku}\")))`,\n\t\t\t\t],\n\t\t\t}) as ProductPagedQueryResponse;\n\n\t\t\tif (items.count === 1) {\n\t\t\t\tproduct = items.results[0];\n\t\t\t}\n\t\t}\n\n\t\tif (!product) {\n\t\t\t// Check if product is found\n\t\t\tthrow new CommercetoolsError<GeneralError>({\n\t\t\t\tcode: \"General\",\n\t\t\t\tmessage: sku\n\t\t\t\t\t? `A product containing a variant with SKU '${sku}' not found.`\n\t\t\t\t\t: `A product with ID '${productId}' not found.`,\n\t\t\t});\n\t\t}\n\n\t\tlet varId: number | undefined = variantId;\n\t\tif (sku) {\n\t\t\tvarId = [\n\t\t\t\tproduct.masterData.current.masterVariant,\n\t\t\t\t...product.masterData.current.variants,\n\t\t\t].find((x) => x.sku === sku)?.id;\n\t\t}\n\t\tif (!varId) {\n\t\t\tvarId = product.masterData.current.masterVariant.id;\n\t\t}\n\n\t\tconst alreadyAdded = resource.lineItems.some(\n\t\t\t(x) => x.productId === product?.id && x.variantId === varId,\n\t\t);\n\t\tif (alreadyAdded) {\n\t\t\t// increase quantity and update total price\n\t\t\tresource.lineItems.forEach((x) => {\n\t\t\t\tif (x.productId === product?.id && x.variantId === varId) {\n\t\t\t\t\tx.quantity += quantity;\n\t\t\t\t}\n\t\t\t});\n\t\t} else {\n\t\t\t// add line item\n\t\t\tresource.lineItems.push({\n\t\t\t\taddedAt: addedAt ? addedAt : new Date().toISOString(),\n\t\t\t\tid: uuidv4(),\n\t\t\t\tkey,\n\t\t\t\tproductId: product.id,\n\t\t\t\tproductSlug: product.masterData.current.slug,\n\t\t\t\tproductType: product.productType,\n\t\t\t\tname: product.masterData.current.name,\n\t\t\t\tvariantId: varId,\n\t\t\t\tquantity,\n\t\t\t\tpublished: Boolean(product.masterData.current),\n\t\t\t});\n\t\t}\n\t}\n\n\tchangeLineItemQuantity(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<ShoppingList>,\n\t\t{\n\t\t\tlineItemId,\n\t\t\tlineItemKey,\n\t\t\tquantity,\n\t\t}: ShoppingListChangeLineItemQuantityAction,\n\t) {\n\t\tlet lineItem: Writable<ShoppingListLineItem> | undefined;\n\n\t\tif (lineItemId) {\n\t\t\tlineItem = resource.lineItems.find((x) => x.id === lineItemId);\n\t\t\tif (!lineItem) {\n\t\t\t\tthrow new CommercetoolsError<GeneralError>({\n\t\t\t\t\tcode: \"General\",\n\t\t\t\t\tmessage: `A line item with ID '${lineItemId}' not found.`,\n\t\t\t\t});\n\t\t\t}\n\t\t} else if (lineItemKey) {\n\t\t\tlineItem = resource.lineItems.find((x) => x.id === lineItemId);\n\t\t\tif (!lineItem) {\n\t\t\t\tthrow new CommercetoolsError<GeneralError>({\n\t\t\t\t\tcode: \"General\",\n\t\t\t\t\tmessage: `A line item with Key '${lineItemKey}' not found.`,\n\t\t\t\t});\n\t\t\t}\n\t\t} else {\n\t\t\tthrow new CommercetoolsError<GeneralError>({\n\t\t\t\tcode: \"General\",\n\t\t\t\tmessage: \"Either lineItemid or lineItemKey needs to be provided.\",\n\t\t\t});\n\t\t}\n\n\t\tif (quantity === 0) {\n\t\t\t// delete line item\n\t\t\tresource.lineItems = resource.lineItems.filter(\n\t\t\t\t(x) => x.id !== lineItemId,\n\t\t\t);\n\t\t} else {\n\t\t\tresource.lineItems.forEach((x) => {\n\t\t\t\tif (x.id === lineItemId && quantity) {\n\t\t\t\t\tx.quantity = quantity;\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t}\n\n\tchangeName(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<ShoppingList>,\n\t\t{ name }: ShoppingListChangeNameAction,\n\t) {\n\t\tresource.name = name;\n\t}\n\n\tremoveLineItem(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<ShoppingList>,\n\t\t{ lineItemId, quantity }: ShoppingListRemoveLineItemAction,\n\t) {\n\t\tconst lineItem = resource.lineItems.find((x) => x.id === lineItemId);\n\t\tif (!lineItem) {\n\t\t\t// Check if product is found\n\t\t\tthrow new CommercetoolsError<GeneralError>({\n\t\t\t\tcode: \"General\",\n\t\t\t\tmessage: `A line item with ID '${lineItemId}' not found.`,\n\t\t\t});\n\t\t}\n\n\t\tconst shouldDelete = !quantity || quantity >= lineItem.quantity;\n\t\tif (shouldDelete) {\n\t\t\t// delete line item\n\t\t\tresource.lineItems = resource.lineItems.filter(\n\t\t\t\t(x) => x.id !== lineItemId,\n\t\t\t);\n\t\t} else {\n\t\t\t// decrease quantity and update total price\n\t\t\tresource.lineItems.forEach((x) => {\n\t\t\t\tif (x.id === lineItemId && quantity) {\n\t\t\t\t\tx.quantity -= quantity;\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t}\n\n\tsetAnonymousId(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<ShoppingList>,\n\t\t{ anonymousId }: ShoppingListSetAnonymousIdAction,\n\t) {\n\t\tresource.anonymousId = anonymousId;\n\t}\n\n\tsetCustomer(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<ShoppingList>,\n\t\t{ customer }: ShoppingListSetCustomerAction,\n\t) {\n\t\tif (customer?.key) {\n\t\t\tthrow new Error(\"set customer on shoppinglist by key not implemented\");\n\t\t}\n\t\tif (customer?.id) {\n\t\t\tresource.customer = { typeId: \"customer\", id: customer.id };\n\t\t}\n\t}\n\n\tsetCustomField(\n\t\tcontext: RepositoryContext,\n\t\tresource: ShoppingList,\n\t\t{ name, value }: ShoppingListSetCustomFieldAction,\n\t) {\n\t\tif (!resource.custom) {\n\t\t\tthrow new Error(\"Resource has no custom field\");\n\t\t}\n\t\tresource.custom.fields[name] = value;\n\t}\n\n\tsetCustomType(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<ShoppingList>,\n\t\t{ type, fields }: ShoppingListSetCustomTypeAction,\n\t) {\n\t\tif (!type) {\n\t\t\tresource.custom = undefined;\n\t\t} else {\n\t\t\tconst resolvedType = this._storage.getByResourceIdentifier(\n\t\t\t\tcontext.projectKey,\n\t\t\t\ttype,\n\t\t\t);\n\t\t\tif (!resolvedType) {\n\t\t\t\tthrow new Error(`Type ${type} not found`);\n\t\t\t}\n\n\t\t\tresource.custom = {\n\t\t\t\ttype: {\n\t\t\t\t\ttypeId: \"type\",\n\t\t\t\t\tid: resolvedType.id,\n\t\t\t\t},\n\t\t\t\tfields: fields || {},\n\t\t\t};\n\t\t}\n\t}\n\n\tsetDeleteDaysAfterLastModification(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<ShoppingList>,\n\t\t{\n\t\t\tdeleteDaysAfterLastModification,\n\t\t}: ShoppingListSetDeleteDaysAfterLastModificationAction,\n\t) {\n\t\tresource.deleteDaysAfterLastModification = deleteDaysAfterLastModification;\n\t}\n\n\tsetDescription(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<ShoppingList>,\n\t\t{ description }: ShoppingListSetDescriptionAction,\n\t) {\n\t\tresource.description = description;\n\t}\n\n\tsetKey(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<ShoppingList>,\n\t\t{ key }: ShoppingListSetKeyAction,\n\t) {\n\t\tresource.key = key;\n\t}\n\n\tsetSlug(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<ShoppingList>,\n\t\t{ slug }: ShoppingListSetSlugAction,\n\t) {\n\t\tresource.slug = slug;\n\t}\n\n\tsetStore(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<ShoppingList>,\n\t\t{ store }: ShoppingListSetStoreAction,\n\t) {\n\t\tif (store?.key) {\n\t\t\tresource.store = { typeId: \"store\", key: store.key };\n\t\t}\n\t\tif (store?.id) {\n\t\t\tthrow new Error(\"set store on shoppinglist by id not implemented\");\n\t\t}\n\t}\n}\n","import type {\n\tCustomerReference,\n\tLineItemDraft,\n\tProductPagedQueryResponse,\n\tShoppingList,\n\tShoppingListDraft,\n\tShoppingListLineItem,\n} from \"@commercetools/platform-sdk\";\nimport type { Config } from \"#src/config.ts\";\nimport { getBaseResourceProperties } from \"../../helpers.ts\";\nimport type { Writable } from \"../../types.ts\";\nimport type { RepositoryContext } from \"../abstract.ts\";\nimport { AbstractResourceRepository } from \"../abstract.ts\";\nimport {\n\tcreateCustomFields,\n\tgetBusinessUnitKeyReference,\n\tgetReferenceFromResourceIdentifier,\n\tgetStoreKeyReference,\n} from \"../helpers.ts\";\nimport { ShoppingListUpdateHandler } from \"./actions.ts\";\n\nexport class ShoppingListRepository extends AbstractResourceRepository<\"shopping-list\"> {\n\tconstructor(config: Config) {\n\t\tsuper(\"shopping-list\", config);\n\t\tthis.actions = new ShoppingListUpdateHandler(config.storage);\n\t}\n\n\tcreate(context: RepositoryContext, draft: ShoppingListDraft): ShoppingList {\n\t\tconst lineItems =\n\t\t\tdraft.lineItems?.map((draftLineItem) =>\n\t\t\t\tthis.draftLineItemtoLineItem(context.projectKey, draftLineItem),\n\t\t\t) ?? [];\n\n\t\tconst resource: ShoppingList = {\n\t\t\t...getBaseResourceProperties(),\n\t\t\t...draft,\n\t\t\tcustom: createCustomFields(\n\t\t\t\tdraft.custom,\n\t\t\t\tcontext.projectKey,\n\t\t\t\tthis._storage,\n\t\t\t),\n\t\t\ttextLineItems: [],\n\t\t\tlineItems,\n\t\t\tcustomer: draft.customer\n\t\t\t\t? getReferenceFromResourceIdentifier<CustomerReference>(\n\t\t\t\t\t\tdraft.customer,\n\t\t\t\t\t\tcontext.projectKey,\n\t\t\t\t\t\tthis._storage,\n\t\t\t\t\t)\n\t\t\t\t: undefined,\n\t\t\tstore: draft.store\n\t\t\t\t? getStoreKeyReference(draft.store, context.projectKey, this._storage)\n\t\t\t\t: undefined,\n\t\t\tbusinessUnit: draft.businessUnit\n\t\t\t\t? getBusinessUnitKeyReference(\n\t\t\t\t\t\tdraft.businessUnit,\n\t\t\t\t\t\tcontext.projectKey,\n\t\t\t\t\t\tthis._storage,\n\t\t\t\t\t)\n\t\t\t\t: undefined,\n\t\t};\n\t\treturn this.saveNew(context, resource);\n\t}\n\n\tdraftLineItemtoLineItem = (\n\t\tprojectKey: string,\n\t\tdraftLineItem: LineItemDraft,\n\t): ShoppingListLineItem => {\n\t\tconst { sku, productId, variantId } = draftLineItem;\n\n\t\tconst lineItem: Writable<ShoppingListLineItem> = {\n\t\t\t...getBaseResourceProperties(),\n\t\t\t...draftLineItem,\n\t\t\taddedAt: draftLineItem.addedAt ?? \"\",\n\t\t\tproductId: draftLineItem.productId ?? \"\",\n\t\t\tname: {},\n\t\t\tvariantId,\n\t\t\tpublished: true,\n\t\t\tquantity: draftLineItem.quantity ?? 1,\n\t\t\tproductType: { typeId: \"product-type\", id: \"\" },\n\t\t\tcustom: createCustomFields(\n\t\t\t\tdraftLineItem.custom,\n\t\t\t\tprojectKey,\n\t\t\t\tthis._storage,\n\t\t\t),\n\t\t};\n\n\t\tif (productId && variantId) {\n\t\t\treturn lineItem;\n\t\t}\n\n\t\tif (sku) {\n\t\t\tconst items = this._storage.query(projectKey, \"product\", {\n\t\t\t\twhere: [\n\t\t\t\t\t`masterData(current(masterVariant(sku=\"${sku}\"))) or masterData(current(variants(sku=\"${sku}\")))`,\n\t\t\t\t],\n\t\t\t}) as ProductPagedQueryResponse;\n\n\t\t\tif (items.count === 0) {\n\t\t\t\tthrow new Error(`Product with sku ${sku} not found`);\n\t\t\t}\n\n\t\t\tconst product = items.results[0];\n\t\t\tconst allVariants = [\n\t\t\t\tproduct.masterData.current.masterVariant,\n\t\t\t\t...product.masterData.current.variants,\n\t\t\t];\n\t\t\tconst variantId = allVariants.find((e) => e.sku === sku)?.id;\n\t\t\tlineItem.variantId = variantId;\n\t\t\tlineItem.productId = product.id;\n\t\t\treturn lineItem;\n\t\t}\n\n\t\tif (productId) {\n\t\t\tconst items = this._storage.query(projectKey, \"product\", {\n\t\t\t\twhere: [`id=\"${productId}\"`],\n\t\t\t}) as ProductPagedQueryResponse;\n\n\t\t\tif (items.count === 0) {\n\t\t\t\tthrow new Error(`Product with id ${productId} not found`);\n\t\t\t}\n\n\t\t\tconst variantId = items.results[0].masterData.current.masterVariant.id;\n\t\t\tlineItem.variantId = variantId;\n\t\t\treturn lineItem;\n\t\t}\n\n\t\tthrow new Error(\n\t\t\t\"must provide either sku, productId or variantId for ShoppingListLineItem\",\n\t\t);\n\t};\n}\n","import type {\n\tChannelReference,\n\tChannelResourceIdentifier,\n\tDiscountedPriceDraft,\n\tStandalonePrice,\n\tStandalonePriceChangeActiveAction,\n\tStandalonePriceChangeValueAction,\n\tStandalonePriceDraft,\n\tStandalonePriceSetDiscountedPriceAction,\n\tStandalonePriceUpdateAction,\n} from \"@commercetools/platform-sdk\";\nimport type { Config } from \"#src/config.ts\";\nimport { getBaseResourceProperties } from \"../helpers.ts\";\nimport type { Writable } from \"../types.ts\";\nimport type { RepositoryContext, UpdateHandlerInterface } from \"./abstract.ts\";\nimport {\n\tAbstractResourceRepository,\n\tAbstractUpdateHandler,\n} from \"./abstract.ts\";\nimport { createTypedMoney } from \"./helpers.ts\";\n\nexport class StandAlonePriceRepository extends AbstractResourceRepository<\"standalone-price\"> {\n\tconstructor(config: Config) {\n\t\tsuper(\"standalone-price\", config);\n\t\tthis.actions = new StandalonePriceUpdateHandler(this._storage);\n\t}\n\n\tcreate(\n\t\tcontext: RepositoryContext,\n\t\tdraft: StandalonePriceDraft,\n\t): StandalonePrice {\n\t\tconst resource: StandalonePrice = {\n\t\t\t...getBaseResourceProperties(),\n\t\t\tactive: draft.active ? draft.active : false,\n\t\t\tsku: draft.sku,\n\t\t\tvalue: createTypedMoney(draft.value),\n\t\t\tcountry: draft.country,\n\t\t\tdiscounted: draft.discounted\n\t\t\t\t? transformDiscountDraft(draft.discounted)\n\t\t\t\t: undefined,\n\t\t\tchannel: draft.channel?.id\n\t\t\t\t? this.transformChannelReferenceDraft(draft.channel)\n\t\t\t\t: undefined,\n\t\t\tvalidFrom: draft.validFrom,\n\t\t\tvalidUntil: draft.validUntil,\n\t\t};\n\t\treturn this.saveNew(context, resource);\n\t}\n\n\ttransformChannelReferenceDraft(\n\t\tchannel: ChannelResourceIdentifier,\n\t): ChannelReference {\n\t\treturn {\n\t\t\ttypeId: channel.typeId,\n\t\t\tid: channel.id as string,\n\t\t};\n\t}\n}\n\nconst transformDiscountDraft = (discounted: DiscountedPriceDraft) => ({\n\tvalue: createTypedMoney(discounted.value),\n\tdiscount: discounted.discount,\n});\n\nclass StandalonePriceUpdateHandler\n\textends AbstractUpdateHandler\n\timplements\n\t\tPartial<\n\t\t\tUpdateHandlerInterface<StandalonePrice, StandalonePriceUpdateAction>\n\t\t>\n{\n\tchangeValue(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<StandalonePrice>,\n\t\taction: StandalonePriceChangeValueAction,\n\t) {\n\t\tresource.value = createTypedMoney(action.value);\n\t}\n\n\tsetActive(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<StandalonePrice>,\n\t\taction: StandalonePriceChangeActiveAction,\n\t) {\n\t\tresource.active = action.active;\n\t}\n\n\tsetDiscountedPrice(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<StandalonePrice>,\n\t\taction: StandalonePriceSetDiscountedPriceAction,\n\t) {\n\t\tresource.discounted = action.discounted\n\t\t\t? transformDiscountDraft(action.discounted)\n\t\t\t: undefined;\n\t}\n}\n","import type {\n\tState,\n\tStateAddRolesAction,\n\tStateChangeInitialAction,\n\tStateChangeKeyAction,\n\tStateChangeTypeAction,\n\tStateDraft,\n\tStateReference,\n\tStateRemoveRolesAction,\n\tStateSetDescriptionAction,\n\tStateSetNameAction,\n\tStateSetRolesAction,\n\tStateSetTransitionsAction,\n\tStateUpdateAction,\n} from \"@commercetools/platform-sdk\";\nimport type { Config } from \"#src/config.ts\";\nimport { getBaseResourceProperties } from \"../helpers.ts\";\nimport type { Writable } from \"../types.ts\";\nimport type { RepositoryContext, UpdateHandlerInterface } from \"./abstract.ts\";\nimport {\n\tAbstractResourceRepository,\n\tAbstractUpdateHandler,\n} from \"./abstract.ts\";\nimport { getReferenceFromResourceIdentifier } from \"./helpers.ts\";\n\nexport class StateRepository extends AbstractResourceRepository<\"state\"> {\n\tconstructor(config: Config) {\n\t\tsuper(\"state\", config);\n\t\tthis.actions = new StateUpdateHandler(config.storage);\n\t}\n\n\tcreate(context: RepositoryContext, draft: StateDraft): State {\n\t\tconst resource: State = {\n\t\t\t...getBaseResourceProperties(),\n\t\t\t...draft,\n\t\t\tbuiltIn: false,\n\t\t\tinitial: draft.initial || false,\n\t\t\ttransitions: (draft.transitions || []).map((t) =>\n\t\t\t\tgetReferenceFromResourceIdentifier(\n\t\t\t\t\tt,\n\t\t\t\t\tcontext.projectKey,\n\t\t\t\t\tthis._storage,\n\t\t\t\t),\n\t\t\t),\n\t\t};\n\n\t\treturn this.saveNew(context, resource);\n\t}\n}\n\nclass StateUpdateHandler\n\textends AbstractUpdateHandler\n\timplements UpdateHandlerInterface<State, StateUpdateAction>\n{\n\taddRoles(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<State>,\n\t\taction: StateAddRolesAction,\n\t) {\n\t\tif (!resource.roles) {\n\t\t\tresource.roles = [];\n\t\t}\n\t\tfor (const role of action.roles) {\n\t\t\tif (!resource.roles.includes(role)) {\n\t\t\t\tresource.roles.push(role);\n\t\t\t}\n\t\t}\n\t}\n\n\tchangeInitial(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<State>,\n\t\t{ initial }: StateChangeInitialAction,\n\t) {\n\t\tresource.initial = initial;\n\t}\n\n\tchangeKey(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<State>,\n\t\t{ key }: StateChangeKeyAction,\n\t) {\n\t\tresource.key = key;\n\t}\n\n\tchangeType(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<State>,\n\t\taction: StateChangeTypeAction,\n\t) {\n\t\tresource.type = action.type;\n\t}\n\n\tremoveRoles(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<State>,\n\t\taction: StateRemoveRolesAction,\n\t) {\n\t\tresource.roles = resource.roles?.filter(\n\t\t\t(role) => !action.roles.includes(role),\n\t\t);\n\t}\n\n\tsetDescription(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<State>,\n\t\t{ description }: StateSetDescriptionAction,\n\t) {\n\t\tresource.description = description;\n\t}\n\n\tsetName(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<State>,\n\t\t{ name }: StateSetNameAction,\n\t) {\n\t\tresource.name = name;\n\t}\n\n\tsetRoles(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<State>,\n\t\t{ roles }: StateSetRolesAction,\n\t) {\n\t\tresource.roles = roles;\n\t}\n\n\tsetTransitions(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<State>,\n\t\t{ transitions }: StateSetTransitionsAction,\n\t) {\n\t\tresource.transitions = transitions?.map(\n\t\t\t(resourceId): StateReference => ({\n\t\t\t\tid: resourceId.id || \"\",\n\t\t\t\ttypeId: \"state\",\n\t\t\t}),\n\t\t);\n\t}\n}\n","import type {\n\tChannelReference,\n\tChannelResourceIdentifier,\n\tStore,\n\tStoreDraft,\n\tStoreSetCountriesAction,\n\tStoreSetCustomFieldAction,\n\tStoreSetCustomTypeAction,\n\tStoreSetDistributionChannelsAction,\n\tStoreSetLanguagesAction,\n\tStoreSetNameAction,\n\tStoreUpdateAction,\n} from \"@commercetools/platform-sdk\";\nimport type { Config } from \"#src/config.ts\";\nimport { getBaseResourceProperties } from \"../helpers.ts\";\nimport type { AbstractStorage } from \"../storage/abstract.ts\";\nimport type { Writable } from \"../types.ts\";\nimport type { RepositoryContext, UpdateHandlerInterface } from \"./abstract.ts\";\nimport {\n\tAbstractResourceRepository,\n\tAbstractUpdateHandler,\n} from \"./abstract.ts\";\nimport {\n\tcreateCustomFields,\n\tgetReferenceFromResourceIdentifier,\n} from \"./helpers.ts\";\n\nexport class StoreRepository extends AbstractResourceRepository<\"store\"> {\n\tconstructor(config: Config) {\n\t\tsuper(\"store\", config);\n\t\tthis.actions = new StoreUpdateHandler(this._storage);\n\t}\n\n\tcreate(context: RepositoryContext, draft: StoreDraft): Store {\n\t\tconst resource: Store = {\n\t\t\t...getBaseResourceProperties(),\n\t\t\tkey: draft.key,\n\t\t\tname: draft.name,\n\t\t\tlanguages: draft.languages ?? [],\n\t\t\tcountries: draft.countries ?? [],\n\t\t\tdistributionChannels: transformChannels(\n\t\t\t\tcontext,\n\t\t\t\tthis._storage,\n\t\t\t\tdraft.distributionChannels,\n\t\t\t),\n\t\t\tsupplyChannels: transformChannels(\n\t\t\t\tcontext,\n\t\t\t\tthis._storage,\n\t\t\t\tdraft.supplyChannels,\n\t\t\t),\n\t\t\tproductSelections: [],\n\t\t\tcustom: createCustomFields(\n\t\t\t\tdraft.custom,\n\t\t\t\tcontext.projectKey,\n\t\t\t\tthis._storage,\n\t\t\t),\n\t\t};\n\t\treturn this.saveNew(context, resource);\n\t}\n}\n\nconst transformChannels = (\n\tcontext: RepositoryContext,\n\tstorage: AbstractStorage,\n\tchannels?: ChannelResourceIdentifier[],\n) => {\n\tif (!channels) return [];\n\n\treturn channels.map((ref) =>\n\t\tgetReferenceFromResourceIdentifier<ChannelReference>(\n\t\t\tref,\n\t\t\tcontext.projectKey,\n\t\t\tstorage,\n\t\t),\n\t);\n};\n\nclass StoreUpdateHandler\n\textends AbstractUpdateHandler\n\timplements Partial<UpdateHandlerInterface<Store, StoreUpdateAction>>\n{\n\tsetCountries(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Store>,\n\t\t{ countries }: StoreSetCountriesAction,\n\t) {\n\t\tresource.countries = countries ?? [];\n\t}\n\n\tsetCustomField(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Store>,\n\t\t{ name, value }: StoreSetCustomFieldAction,\n\t) {\n\t\tif (!resource.custom) {\n\t\t\treturn;\n\t\t}\n\t\tif (value === null) {\n\t\t\tdelete resource.custom.fields[name];\n\t\t} else {\n\t\t\tresource.custom.fields[name] = value;\n\t\t}\n\t}\n\n\tsetCustomType(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Store>,\n\t\t{ type, fields }: StoreSetCustomTypeAction,\n\t) {\n\t\tif (type) {\n\t\t\tresource.custom = createCustomFields(\n\t\t\t\t{ type, fields },\n\t\t\t\tcontext.projectKey,\n\t\t\t\tthis._storage,\n\t\t\t);\n\t\t} else {\n\t\t\tresource.custom = undefined;\n\t\t}\n\t}\n\n\tsetDistributionChannels(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Store>,\n\t\t{ distributionChannels }: StoreSetDistributionChannelsAction,\n\t) {\n\t\tresource.distributionChannels = transformChannels(\n\t\t\tcontext,\n\t\t\tthis._storage,\n\t\t\tdistributionChannels,\n\t\t);\n\t}\n\n\tsetLanguages(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Store>,\n\t\t{ languages }: StoreSetLanguagesAction,\n\t) {\n\t\tresource.languages = languages ?? [];\n\t}\n\n\tsetName(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Store>,\n\t\t{ name }: StoreSetNameAction,\n\t) {\n\t\tresource.name = name;\n\t}\n}\n","import type {\n\tInvalidInputError,\n\tSubscription,\n\tSubscriptionDraft,\n\tSubscriptionSetKeyAction,\n\tSubscriptionUpdateAction,\n} from \"@commercetools/platform-sdk\";\nimport type { Config } from \"#src/config.ts\";\nimport { CommercetoolsError } from \"#src/exceptions.ts\";\nimport { getBaseResourceProperties } from \"../helpers.ts\";\nimport type { Writable } from \"../types.ts\";\nimport type { RepositoryContext, UpdateHandlerInterface } from \"./abstract.ts\";\nimport {\n\tAbstractResourceRepository,\n\tAbstractUpdateHandler,\n} from \"./abstract.ts\";\n\nexport class SubscriptionRepository extends AbstractResourceRepository<\"subscription\"> {\n\tconstructor(config: Config) {\n\t\tsuper(\"subscription\", config);\n\t\tthis.actions = new SubscriptionUpdateHandler(config.storage);\n\t}\n\n\tcreate(context: RepositoryContext, draft: SubscriptionDraft): Subscription {\n\t\t// TODO: We could actually test this here by using the aws sdk. For now\n\t\t// hardcode a failed check when account id is 0000000000\n\t\tif (draft.destination.type === \"SQS\") {\n\t\t\tconst queueURL = new URL(draft.destination.queueUrl);\n\t\t\tconst accountId = queueURL.pathname.split(\"/\")[1];\n\t\t\tif (accountId === \"0000000000\") {\n\t\t\t\tconst dest = draft.destination;\n\t\t\t\tthrow new CommercetoolsError<InvalidInputError>(\n\t\t\t\t\t{\n\t\t\t\t\t\tcode: \"InvalidInput\",\n\t\t\t\t\t\tmessage: `A test message could not be delivered to this destination: SQS ${dest.queueUrl} in ${dest.region} for ${dest.accessKey}. Please make sure your destination is correctly configured.`,\n\t\t\t\t\t},\n\t\t\t\t\t400,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tconst resource: Subscription = {\n\t\t\t...getBaseResourceProperties(),\n\t\t\tchanges: draft.changes || [],\n\t\t\tdestination: draft.destination,\n\t\t\tformat: draft.format || {\n\t\t\t\ttype: \"Platform\",\n\t\t\t},\n\t\t\tkey: draft.key,\n\t\t\tmessages: draft.messages || [],\n\t\t\tstatus: \"Healthy\",\n\t\t\tevents: draft.events || [],\n\t\t};\n\t\treturn this.saveNew(context, resource);\n\t}\n}\n\nclass SubscriptionUpdateHandler\n\textends AbstractUpdateHandler\n\timplements\n\t\tPartial<UpdateHandlerInterface<Subscription, SubscriptionUpdateAction>>\n{\n\tsetKey(\n\t\t_context: RepositoryContext,\n\t\tresource: Writable<Subscription>,\n\t\t{ key }: SubscriptionSetKeyAction,\n\t) {\n\t\tresource.key = key;\n\t}\n}\n","import type { TaxRate, TaxRateDraft } from \"@commercetools/platform-sdk\";\nimport { v4 as uuidv4 } from \"uuid\";\n\nexport const taxRateFromTaxRateDraft = (draft: TaxRateDraft): TaxRate => ({\n\t...draft,\n\tid: uuidv4(),\n\tamount: draft.amount || 0,\n});\n","import type {\n\tTaxCategory,\n\tTaxCategoryAddTaxRateAction,\n\tTaxCategoryChangeNameAction,\n\tTaxCategoryRemoveTaxRateAction,\n\tTaxCategoryReplaceTaxRateAction,\n\tTaxCategorySetDescriptionAction,\n\tTaxCategorySetKeyAction,\n\tTaxCategoryUpdateAction,\n} from \"@commercetools/platform-sdk\";\nimport type { Writable } from \"#src/types.ts\";\nimport type { RepositoryContext } from \"../abstract.ts\";\nimport { AbstractUpdateHandler } from \"../abstract.ts\";\nimport { taxRateFromTaxRateDraft } from \"./helpers.ts\";\n\ntype TaxCategoryUpdateHandlerMethod<T> = (\n\tcontext: RepositoryContext,\n\tresource: Writable<TaxCategory>,\n\taction: T,\n) => void;\n\ntype TaxCategoryUpdateActions = {\n\t[P in TaxCategoryUpdateAction as P[\"action\"]]: TaxCategoryUpdateHandlerMethod<P>;\n};\n\nexport class TaxCategoryUpdateHandler\n\textends AbstractUpdateHandler\n\timplements TaxCategoryUpdateActions\n{\n\taddTaxRate(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<TaxCategory>,\n\t\t{ taxRate }: TaxCategoryAddTaxRateAction,\n\t) {\n\t\tif (resource.rates === undefined) {\n\t\t\tresource.rates = [];\n\t\t}\n\t\tresource.rates.push(taxRateFromTaxRateDraft(taxRate));\n\t}\n\n\tchangeName(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<TaxCategory>,\n\t\t{ name }: TaxCategoryChangeNameAction,\n\t) {\n\t\tresource.name = name;\n\t}\n\n\tremoveTaxRate(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<TaxCategory>,\n\t\t{ taxRateId }: TaxCategoryRemoveTaxRateAction,\n\t) {\n\t\tif (resource.rates === undefined) {\n\t\t\tresource.rates = [];\n\t\t}\n\t\tresource.rates = resource.rates.filter(\n\t\t\t(taxRate) => taxRate.id !== taxRateId,\n\t\t);\n\t}\n\n\treplaceTaxRate(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<TaxCategory>,\n\t\t{ taxRateId, taxRate }: TaxCategoryReplaceTaxRateAction,\n\t) {\n\t\tif (resource.rates === undefined) {\n\t\t\tresource.rates = [];\n\t\t}\n\n\t\tconst taxRateObj = taxRateFromTaxRateDraft(taxRate);\n\t\tfor (let i = 0; i < resource.rates.length; i++) {\n\t\t\tconst rate = resource.rates[i];\n\t\t\tif (rate.id === taxRateId) {\n\t\t\t\tresource.rates[i] = taxRateObj;\n\t\t\t}\n\t\t}\n\t}\n\n\tsetDescription(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<TaxCategory>,\n\t\t{ description }: TaxCategorySetDescriptionAction,\n\t) {\n\t\tresource.description = description;\n\t}\n\n\tsetKey(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<TaxCategory>,\n\t\t{ key }: TaxCategorySetKeyAction,\n\t) {\n\t\tresource.key = key;\n\t}\n}\n","import type {\n\tTaxCategory,\n\tTaxCategoryDraft,\n} from \"@commercetools/platform-sdk\";\nimport type { Config } from \"#src/config.ts\";\nimport { getBaseResourceProperties } from \"#src/helpers.ts\";\nimport type { RepositoryContext } from \"../abstract.ts\";\nimport { AbstractResourceRepository } from \"../abstract.ts\";\nimport { TaxCategoryUpdateHandler } from \"./actions.ts\";\nimport { taxRateFromTaxRateDraft } from \"./helpers.ts\";\n\nexport class TaxCategoryRepository extends AbstractResourceRepository<\"tax-category\"> {\n\tconstructor(config: Config) {\n\t\tsuper(\"tax-category\", config);\n\t\tthis.actions = new TaxCategoryUpdateHandler(this._storage);\n\t}\n\n\tcreate(context: RepositoryContext, draft: TaxCategoryDraft): TaxCategory {\n\t\tconst resource: TaxCategory = {\n\t\t\t...getBaseResourceProperties(),\n\t\t\t...draft,\n\t\t\trates: draft.rates?.map(taxRateFromTaxRateDraft) || [],\n\t\t};\n\t\treturn this.saveNew(context, resource);\n\t}\n}\n","import { isDeepStrictEqual } from \"node:util\";\nimport type {\n\tFieldDefinition,\n\tInvalidOperationError,\n\tType,\n\tTypeAddEnumValueAction,\n\tTypeAddFieldDefinitionAction,\n\tTypeChangeEnumValueLabelAction,\n\tTypeChangeFieldDefinitionOrderAction,\n\tTypeChangeNameAction,\n\tTypeRemoveFieldDefinitionAction,\n\tTypeSetDescriptionAction,\n\tTypeUpdateAction,\n} from \"@commercetools/platform-sdk\";\nimport { CommercetoolsError } from \"#src/exceptions.ts\";\nimport type { Writable } from \"#src/types.ts\";\nimport type { RepositoryContext } from \"../abstract.ts\";\nimport { AbstractUpdateHandler } from \"../abstract.ts\";\n\ntype TypeUpdateHandlerMethod<T> = (\n\tcontext: RepositoryContext,\n\tresource: Writable<Type>,\n\taction: T,\n) => void;\n\ntype TypeUpdateActions = Partial<{\n\t[P in TypeUpdateAction as P[\"action\"]]: TypeUpdateHandlerMethod<P>;\n}>;\n\nexport class TypeUpdateHandler\n\textends AbstractUpdateHandler\n\timplements TypeUpdateActions\n{\n\taddEnumValue(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Type>,\n\t\t{ fieldName, value }: TypeAddEnumValueAction,\n\t) {\n\t\tresource.fieldDefinitions.forEach((field) => {\n\t\t\tif (field.name === fieldName) {\n\t\t\t\t// TODO, should be done better i suppose\n\t\t\t\tif (field.type.name === \"Enum\") {\n\t\t\t\t\tfield.type.values.push(value);\n\t\t\t\t} else if (\n\t\t\t\t\tfield.type.name === \"Set\" &&\n\t\t\t\t\tfield.type.elementType.name === \"Enum\"\n\t\t\t\t) {\n\t\t\t\t\tfield.type.elementType.values.push(value);\n\t\t\t\t} else {\n\t\t\t\t\tthrow new Error(\"Type is not a Enum (or Set of Enum)\");\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t}\n\n\taddFieldDefinition(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Type>,\n\t\t{ fieldDefinition }: TypeAddFieldDefinitionAction,\n\t) {\n\t\tresource.fieldDefinitions.push(fieldDefinition);\n\t}\n\n\tchangeEnumValueLabel(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Type>,\n\t\t{ fieldName, value }: TypeChangeEnumValueLabelAction,\n\t) {\n\t\tresource.fieldDefinitions.forEach((field) => {\n\t\t\tif (field.name === fieldName) {\n\t\t\t\t// TODO, should be done better i suppose\n\t\t\t\tif (field.type.name === \"Enum\") {\n\t\t\t\t\tfield.type.values.forEach((v) => {\n\t\t\t\t\t\tif (v.key === value.key) {\n\t\t\t\t\t\t\tv.label = value.label;\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t} else if (\n\t\t\t\t\tfield.type.name === \"Set\" &&\n\t\t\t\t\tfield.type.elementType.name === \"Enum\"\n\t\t\t\t) {\n\t\t\t\t\tfield.type.elementType.values.forEach((v) => {\n\t\t\t\t\t\tif (v.key === value.key) {\n\t\t\t\t\t\t\tv.label = value.label;\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\tthrow new Error(\"Type is not a Enum (or Set of Enum)\");\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t}\n\n\tchangeFieldDefinitionOrder(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Type>,\n\t\t{ fieldNames }: TypeChangeFieldDefinitionOrderAction,\n\t) {\n\t\tconst fields = new Map(\n\t\t\tresource.fieldDefinitions.map((item) => [item.name, item]),\n\t\t);\n\t\tconst result: FieldDefinition[] = [];\n\t\tlet current = resource.fieldDefinitions;\n\n\t\tfieldNames.forEach((fieldName) => {\n\t\t\tconst field = fields.get(fieldName);\n\t\t\tif (field === undefined) {\n\t\t\t\tthrow new Error(\"New field\");\n\t\t\t}\n\t\t\tresult.push(field);\n\n\t\t\t// Remove from current items\n\t\t\tcurrent = current.filter((f) => f.name !== fieldName);\n\t\t});\n\n\t\tif (\n\t\t\tisDeepStrictEqual(\n\t\t\t\tfieldNames,\n\t\t\t\tresource.fieldDefinitions.map((item) => item.name),\n\t\t\t)\n\t\t) {\n\t\t\tthrow new CommercetoolsError<InvalidOperationError>({\n\t\t\t\tcode: \"InvalidOperation\",\n\t\t\t\tmessage: \"'fieldDefinitions' has no changes.\",\n\t\t\t\taction: {\n\t\t\t\t\taction: \"changeFieldDefinitionOrder\",\n\t\t\t\t\tfieldNames: fieldNames,\n\t\t\t\t},\n\t\t\t});\n\t\t}\n\n\t\tresource.fieldDefinitions = result;\n\t\t// Add fields which were not specified in the order as last items. Not\n\t\t// sure if this follows commercetools\n\t\tresource.fieldDefinitions.push(...current);\n\t}\n\n\tchangeName(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Type>,\n\t\t{ name }: TypeChangeNameAction,\n\t) {\n\t\tresource.name = name;\n\t}\n\n\tremoveFieldDefinition(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Type>,\n\t\t{ fieldName }: TypeRemoveFieldDefinitionAction,\n\t) {\n\t\tresource.fieldDefinitions = resource.fieldDefinitions.filter(\n\t\t\t(f) => f.name !== fieldName,\n\t\t);\n\t}\n\n\tsetDescription(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Type>,\n\t\t{ description }: TypeSetDescriptionAction,\n\t) {\n\t\tresource.description = description;\n\t}\n}\n","import type { Type, TypeDraft } from \"@commercetools/platform-sdk\";\nimport type { Config } from \"#src/config.ts\";\nimport { getBaseResourceProperties } from \"#src/helpers.ts\";\nimport type { RepositoryContext } from \"../abstract.ts\";\nimport { AbstractResourceRepository } from \"../abstract.ts\";\nimport { TypeUpdateHandler } from \"./actions.ts\";\n\nexport class TypeRepository extends AbstractResourceRepository<\"type\"> {\n\tconstructor(config: Config) {\n\t\tsuper(\"type\", config);\n\t\tthis.actions = new TypeUpdateHandler(config.storage);\n\t}\n\n\tcreate(context: RepositoryContext, draft: TypeDraft): Type {\n\t\tconst resource: Type = {\n\t\t\t...getBaseResourceProperties(),\n\t\t\tkey: draft.key,\n\t\t\tname: draft.name,\n\t\t\tresourceTypeIds: draft.resourceTypeIds,\n\t\t\tfieldDefinitions: draft.fieldDefinitions || [],\n\t\t\tdescription: draft.description,\n\t\t};\n\t\treturn this.saveNew(context, resource);\n\t}\n}\n","import type {\n\tZone,\n\tZoneAddLocationAction,\n\tZoneChangeNameAction,\n\tZoneDraft,\n\tZoneRemoveLocationAction,\n\tZoneSetDescriptionAction,\n\tZoneSetKeyAction,\n\tZoneUpdateAction,\n} from \"@commercetools/platform-sdk\";\nimport type { Config } from \"#src/config.ts\";\nimport { getBaseResourceProperties } from \"../helpers.ts\";\nimport type { Writable } from \"../types.ts\";\nimport type { RepositoryContext, UpdateHandlerInterface } from \"./abstract.ts\";\nimport {\n\tAbstractResourceRepository,\n\tAbstractUpdateHandler,\n} from \"./abstract.ts\";\n\nexport class ZoneRepository extends AbstractResourceRepository<\"zone\"> {\n\tconstructor(config: Config) {\n\t\tsuper(\"zone\", config);\n\t\tthis.actions = new ZoneUpdateHandler(config.storage);\n\t}\n\n\tcreate(context: RepositoryContext, draft: ZoneDraft): Zone {\n\t\tconst resource: Zone = {\n\t\t\t...getBaseResourceProperties(),\n\t\t\tkey: draft.key,\n\t\t\tlocations: draft.locations || [],\n\t\t\tname: draft.name,\n\t\t\tdescription: draft.description,\n\t\t};\n\t\treturn this.saveNew(context, resource);\n\t}\n}\n\nclass ZoneUpdateHandler\n\textends AbstractUpdateHandler\n\timplements Partial<UpdateHandlerInterface<Zone, ZoneUpdateAction>>\n{\n\taddLocation(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Zone>,\n\t\t{ location }: ZoneAddLocationAction,\n\t) {\n\t\tresource.locations.push(location);\n\t}\n\n\tchangeName(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Zone>,\n\t\t{ name }: ZoneChangeNameAction,\n\t) {\n\t\tresource.name = name;\n\t}\n\n\tremoveLocation(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Zone>,\n\t\t{ location }: ZoneRemoveLocationAction,\n\t) {\n\t\tresource.locations = resource.locations.filter(\n\t\t\t(loc) =>\n\t\t\t\t!(loc.country === location.country && loc.state === location.state),\n\t\t);\n\t}\n\n\tsetDescription(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Zone>,\n\t\t{ description }: ZoneSetDescriptionAction,\n\t) {\n\t\tresource.description = description;\n\t}\n\n\tsetKey(\n\t\tcontext: RepositoryContext,\n\t\tresource: Writable<Zone>,\n\t\t{ key }: ZoneSetKeyAction,\n\t) {\n\t\tresource.key = key;\n\t}\n}\n","import type { Config } from \"#src/config.ts\";\nimport { ProductTailoringRepository } from \"#src/repositories/product-tailoring.ts\";\nimport {\n\tAsAssociateCartRepository,\n\tAsAssociateOrderRepository,\n\tAsAssociateQuoteRequestRepository,\n} from \"./as-associate.ts\";\nimport { AssociateRoleRepository } from \"./associate-role.ts\";\nimport { AttributeGroupRepository } from \"./attribute-group.ts\";\nimport { BusinessUnitRepository } from \"./business-unit.ts\";\nimport { CartRepository } from \"./cart/index.ts\";\nimport { CartDiscountRepository } from \"./cart-discount/index.ts\";\nimport { CategoryRepository } from \"./category/index.ts\";\nimport { ChannelRepository } from \"./channel.ts\";\nimport { CustomObjectRepository } from \"./custom-object.ts\";\nimport { CustomerRepository } from \"./customer/index.ts\";\nimport { CustomerGroupRepository } from \"./customer-group.ts\";\nimport { DiscountCodeRepository } from \"./discount-code/index.ts\";\nimport { DiscountGroupRepository } from \"./discount-group/index.ts\";\nimport { ExtensionRepository } from \"./extension.ts\";\nimport { InventoryEntryRepository } from \"./inventory-entry/index.ts\";\nimport { MyCustomerRepository } from \"./my-customer.ts\";\nimport { MyOrderRepository } from \"./my-order.ts\";\nimport { OrderRepository } from \"./order/index.ts\";\nimport { OrderEditRepository } from \"./order-edit.ts\";\nimport { PaymentRepository } from \"./payment/index.ts\";\nimport { ProductRepository } from \"./product/index.ts\";\nimport { ProductDiscountRepository } from \"./product-discount.ts\";\nimport { ProductProjectionRepository } from \"./product-projection.ts\";\nimport { ProductSelectionRepository } from \"./product-selection.ts\";\nimport { ProductTypeRepository } from \"./product-type.ts\";\nimport { ProjectRepository } from \"./project.ts\";\nimport { QuoteRepository } from \"./quote/index.ts\";\nimport { QuoteRequestRepository } from \"./quote-request/index.ts\";\nimport { StagedQuoteRepository } from \"./quote-staged/index.ts\";\nimport { RecurrencePolicyRepository } from \"./recurrence-policy/index.ts\";\nimport { RecurringOrderRepository } from \"./recurring-order/index.ts\";\nimport { ReviewRepository } from \"./review.ts\";\nimport { ShippingMethodRepository } from \"./shipping-method/index.ts\";\nimport { ShoppingListRepository } from \"./shopping-list/index.ts\";\nimport { StandAlonePriceRepository } from \"./standalone-price.ts\";\nimport { StateRepository } from \"./state.ts\";\nimport { StoreRepository } from \"./store.ts\";\nimport { SubscriptionRepository } from \"./subscription.ts\";\nimport { TaxCategoryRepository } from \"./tax-category/index.ts\";\nimport { TypeRepository } from \"./type/index.ts\";\nimport { ZoneRepository } from \"./zone.ts\";\n\nexport type RepositoryMap = ReturnType<typeof createRepositories>;\n\nexport const createRepositories = (config: Config) => ({\n\t\"as-associate\": {\n\t\tcart: new AsAssociateCartRepository(config),\n\t\torder: new AsAssociateOrderRepository(config),\n\t\t\"quote-request\": new AsAssociateQuoteRequestRepository(config),\n\t},\n\t\"associate-role\": new AssociateRoleRepository(config),\n\t\"attribute-group\": new AttributeGroupRepository(config),\n\t\"business-unit\": new BusinessUnitRepository(config),\n\tcategory: new CategoryRepository(config),\n\tcart: new CartRepository(config),\n\t\"cart-discount\": new CartDiscountRepository(config),\n\tcustomer: new CustomerRepository(config),\n\tchannel: new ChannelRepository(config),\n\t\"customer-group\": new CustomerGroupRepository(config),\n\t\"discount-code\": new DiscountCodeRepository(config),\n\t\"discount-group\": new DiscountGroupRepository(config),\n\textension: new ExtensionRepository(config),\n\t\"inventory-entry\": new InventoryEntryRepository(config),\n\t\"key-value-document\": new CustomObjectRepository(config),\n\torder: new OrderRepository(config),\n\t\"order-edit\": new OrderEditRepository(config),\n\tpayment: new PaymentRepository(config),\n\t\"my-cart\": new CartRepository(config),\n\t\"my-order\": new MyOrderRepository(config),\n\t\"my-customer\": new MyCustomerRepository(config),\n\t\"my-payment\": new PaymentRepository(config),\n\t\"my-shopping-list\": new ShoppingListRepository(config),\n\tproduct: new ProductRepository(config),\n\t\"product-type\": new ProductTypeRepository(config),\n\t\"product-discount\": new ProductDiscountRepository(config),\n\t\"product-projection\": new ProductProjectionRepository(config),\n\t\"product-selection\": new ProductSelectionRepository(config),\n\t\"product-tailoring\": new ProductTailoringRepository(config),\n\tproject: new ProjectRepository(config),\n\t\"recurring-order\": new RecurringOrderRepository(config),\n\t\"recurrence-policy\": new RecurrencePolicyRepository(config),\n\treview: new ReviewRepository(config),\n\tquote: new QuoteRepository(config),\n\t\"quote-request\": new QuoteRequestRepository(config),\n\t\"shipping-method\": new ShippingMethodRepository(config),\n\t\"shopping-list\": new ShoppingListRepository(config),\n\t\"staged-quote\": new StagedQuoteRepository(config),\n\t\"standalone-price\": new StandAlonePriceRepository(config),\n\tstate: new StateRepository(config),\n\tstore: new StoreRepository(config),\n\tsubscription: new SubscriptionRepository(config),\n\t\"tax-category\": new TaxCategoryRepository(config),\n\ttype: new TypeRepository(config),\n\tzone: new ZoneRepository(config),\n});\n","import { z } from \"zod\";\n\nconst UpdateActionSchema = z\n\t.object({\n\t\taction: z.string(),\n\t})\n\t.passthrough();\n\nexport const updateRequestSchema = z.object({\n\tversion: z.number(),\n\tactions: z.array(UpdateActionSchema),\n});\n","import type { InvalidJsonInputError } from \"@commercetools/platform-sdk\";\nimport type { z } from \"zod\";\nimport { fromZodError } from \"zod-validation-error\";\nimport { CommercetoolsError } from \"./exceptions.ts\";\n\nexport const validateData = <T>(data: any, schema: z.AnyZodObject) => {\n\ttry {\n\t\tschema.parse(data);\n\t\treturn data as T;\n\t} catch (err: any) {\n\t\tconst validationError = fromZodError(err);\n\t\tthrow new CommercetoolsError<InvalidJsonInputError>({\n\t\t\tcode: \"InvalidJsonInput\",\n\t\t\tmessage: \"Request body does not contain valid JSON.\",\n\t\t\tdetailedErrorMessage: validationError.toString(),\n\t\t});\n\t}\n};\n","import type { Update } from \"@commercetools/platform-sdk\";\nimport { type Request, type Response, Router } from \"express\";\nimport type { ParsedQs } from \"qs\";\nimport { updateRequestSchema } from \"#src/schemas/update-request.ts\";\nimport { validateData } from \"#src/validate.ts\";\nimport { queryParamsArray } from \"../helpers.ts\";\nimport type {\n\tAbstractResourceRepository,\n\tQueryParams,\n} from \"../repositories/abstract.ts\";\nimport { getRepositoryContext } from \"../repositories/helpers.ts\";\n\nexport default abstract class AbstractService {\n\tpublic abstract repository: AbstractResourceRepository<any>;\n\n\tcreateStatusCode = 201;\n\n\tconstructor(parent: Router) {\n\t\tthis.registerRoutes(parent);\n\t}\n\n\tprotected abstract getBasePath(): string;\n\n\textraRoutes(router: Router) {}\n\n\tregisterRoutes(parent: Router) {\n\t\tconst basePath = this.getBasePath();\n\t\tconst router = Router({ mergeParams: true });\n\n\t\t// Bind this first since the `/:id` routes are currently a bit to greedy\n\t\tthis.extraRoutes(router);\n\n\t\trouter.get(\"/\", this.get.bind(this));\n\t\trouter.get(\"/key=:key\", this.getWithKey.bind(this)); // same thing goes for the key routes\n\t\trouter.get(\"/:id\", this.getWithId.bind(this));\n\n\t\trouter.delete(\"/key=:key\", this.deleteWithKey.bind(this));\n\t\trouter.delete(\"/:id\", this.deleteWithId.bind(this));\n\n\t\trouter.post(\"/\", this.post.bind(this));\n\t\trouter.post(\"/key=:key\", this.postWithKey.bind(this));\n\t\trouter.post(\"/:id\", this.postWithId.bind(this));\n\n\t\tparent.use(`/${basePath}`, router);\n\t}\n\n\tget(request: Request, response: Response) {\n\t\tconst limit = this._parseParam(request.query.limit);\n\t\tconst offset = this._parseParam(request.query.offset);\n\t\tconst params: QueryParams = {\n\t\t\texpand: this._parseParam(request.query.expand),\n\t\t\twhere: this._parseParam(request.query.where),\n\t\t\tlimit: limit !== undefined ? Number(limit) : undefined,\n\t\t\toffset: offset !== undefined ? Number(offset) : undefined,\n\t\t};\n\n\t\tfor (const key in request.query) {\n\t\t\tif (key.startsWith(\"var.\")) {\n\t\t\t\tconst items = this._parseParam(request.query[key]);\n\t\t\t\tif (items) {\n\t\t\t\t\tparams[key] = items.length === 1 ? items[0] : items;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tconst result = this.repository.query(getRepositoryContext(request), params);\n\t\tresponse.status(200).send(result);\n\t\treturn;\n\t}\n\n\tgetWithId(request: Request, response: Response) {\n\t\tconst result = this._expandWithId(request, request.params.id);\n\t\tif (!result) {\n\t\t\tresponse.status(404).send({\n\t\t\t\tstatusCode: 404,\n\t\t\t\tmessage: `The Resource with ID '${request.params.id} was not found.`,\n\t\t\t\terrors: [\n\t\t\t\t\t{\n\t\t\t\t\t\tcode: \"ResourceNotFound\",\n\t\t\t\t\t\tmessage: `The Resource with ID '${request.params.id} was not found.`,\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\t\tresponse.status(200).send(result);\n\t}\n\n\tgetWithKey(request: Request, response: Response) {\n\t\tconst result = this.repository.getByKey(\n\t\t\tgetRepositoryContext(request),\n\t\t\trequest.params.key,\n\t\t\t{\n\t\t\t\texpand: this._parseParam(request.query.expand),\n\t\t\t},\n\t\t);\n\t\tif (!result) {\n\t\t\tresponse.status(404).send({\n\t\t\t\tstatusCode: 404,\n\t\t\t\tmessage: `The Resource with key '${request.params.id} was not found.`,\n\t\t\t\terrors: [\n\t\t\t\t\t{\n\t\t\t\t\t\tcode: \"ResourceNotFound\",\n\t\t\t\t\t\tmessage: `The Resource with key '${request.params.id} was not found.`,\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\t\tresponse.status(200).send(result);\n\t}\n\n\tdeleteWithId(request: Request, response: Response) {\n\t\tconst result = this.repository.delete(\n\t\t\tgetRepositoryContext(request),\n\t\t\trequest.params.id,\n\t\t\t{\n\t\t\t\texpand: this._parseParam(request.query.expand),\n\t\t\t},\n\t\t);\n\t\tif (!result) {\n\t\t\tresponse.status(404).send({ statusCode: 404 });\n\t\t\treturn;\n\t\t}\n\t\tresponse.status(200).send(result);\n\t}\n\n\tdeleteWithKey(request: Request, response: Response) {\n\t\tconst resource = this.repository.getByKey(\n\t\t\tgetRepositoryContext(request),\n\t\t\trequest.params.key,\n\t\t);\n\t\tif (!resource) {\n\t\t\tresponse.status(404).send({ statusCode: 404 });\n\t\t\treturn;\n\t\t}\n\n\t\tconst result = this.repository.delete(\n\t\t\tgetRepositoryContext(request),\n\t\t\tresource.id,\n\t\t\t{\n\t\t\t\texpand: this._parseParam(request.query.expand),\n\t\t\t},\n\t\t);\n\t\tif (!result) {\n\t\t\tresponse.status(404).send({ statusCode: 404 });\n\t\t\treturn;\n\t\t}\n\t\tresponse.status(200).send(result);\n\t}\n\n\tpost(request: Request, response: Response) {\n\t\tconst draft = request.body;\n\t\tconst resource = this.repository.create(\n\t\t\tgetRepositoryContext(request),\n\t\t\tdraft,\n\t\t);\n\t\tconst result = this._expandWithId(request, resource.id);\n\t\tresponse.status(this.createStatusCode).send(result);\n\t}\n\n\tpostWithId(request: Request, response: Response) {\n\t\tconst updateRequest = validateData<Update>(\n\t\t\trequest.body,\n\t\t\tupdateRequestSchema,\n\t\t);\n\t\tconst resource = this.repository.get(\n\t\t\tgetRepositoryContext(request),\n\t\t\trequest.params.id,\n\t\t);\n\t\tif (!resource) {\n\t\t\tresponse.status(404).send({ statusCode: 404 });\n\t\t\treturn;\n\t\t}\n\n\t\tconst updatedResource = this.repository.processUpdateActions(\n\t\t\tgetRepositoryContext(request),\n\t\t\tresource,\n\t\t\tupdateRequest.version,\n\t\t\tupdateRequest.actions,\n\t\t);\n\n\t\tconst result = this._expandWithId(request, updatedResource.id);\n\t\tresponse.status(200).send(result);\n\t}\n\n\tpostWithKey(request: Request, response: Response) {\n\t\tconst updateRequest = validateData<Update>(\n\t\t\trequest.body,\n\t\t\tupdateRequestSchema,\n\t\t);\n\n\t\tconst resource = this.repository.getByKey(\n\t\t\tgetRepositoryContext(request),\n\t\t\trequest.params.key,\n\t\t);\n\t\tif (!resource) {\n\t\t\tresponse.status(404).send({ statusCode: 404 });\n\t\t\treturn;\n\t\t}\n\n\t\tconst updatedResource = this.repository.processUpdateActions(\n\t\t\tgetRepositoryContext(request),\n\t\t\tresource,\n\t\t\tupdateRequest.version,\n\t\t\tupdateRequest.actions,\n\t\t);\n\n\t\tconst result = this._expandWithId(request, updatedResource.id);\n\t\tresponse.status(200).send(result);\n\t}\n\n\tprotected _expandWithId(request: Request, resourceId: string) {\n\t\tconst result = this.repository.get(\n\t\t\tgetRepositoryContext(request),\n\t\t\tresourceId,\n\t\t\t{\n\t\t\t\texpand: this._parseParam(request.query.expand),\n\t\t\t},\n\t\t);\n\t\treturn result;\n\t}\n\n\t// No idea what i'm doing\n\tprotected _parseParam(\n\t\tvalue: string | ParsedQs | string[] | ParsedQs[] | undefined,\n\t): string[] | undefined {\n\t\treturn queryParamsArray(value);\n\t}\n}\n","import { Router } from \"express\";\nimport type { CartRepository } from \"../repositories/cart/index.ts\";\nimport AbstractService from \"./abstract.ts\";\n\nexport class AsAssociateCartService extends AbstractService {\n\tpublic repository: CartRepository;\n\n\tconstructor(parent: Router, repository: CartRepository) {\n\t\tsuper(parent);\n\t\tthis.repository = repository;\n\t}\n\n\tgetBasePath() {\n\t\treturn \"carts\";\n\t}\n\n\tregisterRoutes(parent: Router) {\n\t\tconst basePath = this.getBasePath();\n\t\tconst router = Router({ mergeParams: true });\n\n\t\tthis.extraRoutes(router);\n\n\t\trouter.get(\"/\", this.get.bind(this));\n\t\trouter.get(\"/:id\", this.getWithId.bind(this));\n\n\t\trouter.delete(\"/:id\", this.deleteWithId.bind(this));\n\n\t\trouter.post(\"/\", this.post.bind(this));\n\t\trouter.post(\"/:id\", this.postWithId.bind(this));\n\n\t\tparent.use(`/${basePath}`, router);\n\t}\n}\n","import { Router } from \"express\";\nimport type { MyOrderRepository } from \"../repositories/my-order.ts\";\nimport AbstractService from \"./abstract.ts\";\n\nexport class AsAssociateOrderService extends AbstractService {\n\tpublic repository: MyOrderRepository;\n\n\tconstructor(parent: Router, repository: MyOrderRepository) {\n\t\tsuper(parent);\n\t\tthis.repository = repository;\n\t}\n\n\tgetBasePath() {\n\t\treturn \"orders\";\n\t}\n\n\tregisterRoutes(parent: Router) {\n\t\tconst basePath = this.getBasePath();\n\t\tconst router = Router({ mergeParams: true });\n\n\t\tthis.extraRoutes(router);\n\n\t\trouter.get(\"/\", this.get.bind(this));\n\t\trouter.get(\"/:id\", this.getWithId.bind(this));\n\n\t\trouter.delete(\"/:id\", this.deleteWithId.bind(this));\n\n\t\trouter.post(\"/\", this.post.bind(this));\n\t\trouter.post(\"/:id\", this.postWithId.bind(this));\n\n\t\tparent.use(`/${basePath}`, router);\n\t}\n}\n","import { Router } from \"express\";\nimport type { MyQuoteRequestRepository } from \"#src/repositories/my-quote-request.ts\";\nimport AbstractService from \"./abstract.ts\";\n\nexport class AsAssociateQuoteRequestService extends AbstractService {\n\tpublic repository: MyQuoteRequestRepository;\n\n\tconstructor(parent: Router, repository: MyQuoteRequestRepository) {\n\t\tsuper(parent);\n\t\tthis.repository = repository;\n\t}\n\n\tgetBasePath() {\n\t\treturn \"quote-requests\";\n\t}\n\n\tregisterRoutes(parent: Router) {\n\t\tconst basePath = this.getBasePath();\n\t\tconst router = Router({ mergeParams: true });\n\n\t\tthis.extraRoutes(router);\n\n\t\trouter.get(\"/\", this.get.bind(this));\n\t\trouter.get(\"/:id\", this.getWithId.bind(this));\n\n\t\trouter.delete(\"/:id\", this.deleteWithId.bind(this));\n\n\t\trouter.post(\"/\", this.post.bind(this));\n\t\trouter.post(\"/:id\", this.postWithId.bind(this));\n\n\t\tparent.use(`/${basePath}`, router);\n\t}\n}\n","import { Router } from \"express\";\nimport type {\n\tAsAssociateCartRepository,\n\tAsAssociateOrderRepository,\n\tAsAssociateQuoteRequestRepository,\n} from \"#src/repositories/as-associate.ts\";\nimport { AsAssociateCartService } from \"./as-associate-cart.ts\";\nimport { AsAssociateOrderService } from \"./as-associate-order.ts\";\nimport { AsAssociateQuoteRequestService } from \"./as-associate-quote-request.ts\";\n\ntype Repositories = {\n\tcart: AsAssociateCartRepository;\n\torder: AsAssociateOrderRepository;\n\t\"quote-request\": AsAssociateQuoteRequestRepository;\n};\n\nexport class AsAssociateService {\n\trouter: Router;\n\n\tsubServices: {\n\t\tcart: AsAssociateCartService;\n\t\torder: AsAssociateOrderService;\n\t\t\"quote-request\": AsAssociateQuoteRequestService;\n\t};\n\n\tconstructor(parent: Router, repositories: Repositories) {\n\t\tthis.router = Router({ mergeParams: true });\n\n\t\tthis.subServices = {\n\t\t\torder: new AsAssociateOrderService(this.router, repositories.order),\n\t\t\tcart: new AsAssociateCartService(this.router, repositories.cart),\n\t\t\t\"quote-request\": new AsAssociateQuoteRequestService(\n\t\t\t\tthis.router,\n\t\t\t\trepositories[\"quote-request\"],\n\t\t\t),\n\t\t};\n\t\tparent.use(\n\t\t\t\"/as-associate/:associateId/in-business-unit/key=:businessUnitId\",\n\t\t\tthis.router,\n\t\t);\n\t}\n}\n","import type { Router } from \"express\";\nimport type { AssociateRoleRepository } from \"../repositories/associate-role.ts\";\nimport AbstractService from \"./abstract.ts\";\n\nexport class AssociateRoleServices extends AbstractService {\n\tpublic repository: AssociateRoleRepository;\n\n\tconstructor(parent: Router, repository: AssociateRoleRepository) {\n\t\tsuper(parent);\n\n\t\tthis.repository = repository;\n\t}\n\n\tprotected getBasePath(): string {\n\t\treturn \"associate-roles\";\n\t}\n}\n","import type { Router } from \"express\";\nimport type { AttributeGroupRepository } from \"../repositories/attribute-group.ts\";\nimport AbstractService from \"./abstract.ts\";\n\nexport class AttributeGroupService extends AbstractService {\n\tpublic repository: AttributeGroupRepository;\n\n\tconstructor(parent: Router, repository: AttributeGroupRepository) {\n\t\tsuper(parent);\n\t\tthis.repository = repository;\n\t}\n\n\tgetBasePath() {\n\t\treturn \"attribute-groups\";\n\t}\n}\n","import type { Router } from \"express\";\nimport type { BusinessUnitRepository } from \"../repositories/business-unit.ts\";\nimport AbstractService from \"./abstract.ts\";\n\nexport class BusinessUnitServices extends AbstractService {\n\tpublic repository: BusinessUnitRepository;\n\n\tconstructor(parent: Router, repository: BusinessUnitRepository) {\n\t\tsuper(parent);\n\n\t\tthis.repository = repository;\n\t}\n\n\tprotected getBasePath(): string {\n\t\treturn \"business-units\";\n\t}\n}\n","import type { Cart, CartDraft, Order } from \"@commercetools/platform-sdk\";\nimport type { Request, Response, Router } from \"express\";\nimport type { CartRepository } from \"../repositories/cart/index.ts\";\nimport { getRepositoryContext } from \"../repositories/helpers.ts\";\nimport type { OrderRepository } from \"../repositories/order/index.ts\";\nimport AbstractService from \"./abstract.ts\";\n\nexport class CartService extends AbstractService {\n\tpublic repository: CartRepository;\n\n\tpublic orderRepository: OrderRepository;\n\n\tconstructor(\n\t\tparent: Router,\n\t\tcartRepository: CartRepository,\n\t\torderRepository: OrderRepository,\n\t) {\n\t\tsuper(parent);\n\t\tthis.repository = cartRepository;\n\t\tthis.orderRepository = orderRepository;\n\t}\n\n\tgetBasePath() {\n\t\treturn \"carts\";\n\t}\n\n\textraRoutes(parent: Router) {\n\t\tparent.post(\"/replicate\", this.replicate.bind(this));\n\t}\n\n\treplicate(request: Request, response: Response) {\n\t\tconst context = getRepositoryContext(request);\n\n\t\tconst cartOrOrder: Cart | Order | null =\n\t\t\trequest.body.reference.typeId === \"order\"\n\t\t\t\t? this.orderRepository.get(context, request.body.reference.id)\n\t\t\t\t: this.repository.get(context, request.body.reference.id);\n\n\t\tif (!cartOrOrder) {\n\t\t\tresponse.status(400).send();\n\t\t\treturn;\n\t\t}\n\n\t\tconst cartDraft: CartDraft = {\n\t\t\t...cartOrOrder,\n\t\t\tcurrency: cartOrOrder.totalPrice.currencyCode,\n\t\t\tdiscountCodes: [],\n\t\t\tshipping: [], // TODO: cartOrOrder.shipping,\n\t\t\tlineItems: cartOrOrder.lineItems.map((lineItem) => ({\n\t\t\t\t...lineItem,\n\t\t\t\tvariantId: lineItem.variant.id,\n\t\t\t\tsku: lineItem.variant.sku,\n\t\t\t})),\n\t\t};\n\n\t\tconst newCart = this.repository.create(context, cartDraft);\n\n\t\tresponse.status(200).send(newCart);\n\t}\n}\n","import type { Router } from \"express\";\nimport type { CartDiscountRepository } from \"../repositories/cart-discount/index.ts\";\nimport AbstractService from \"./abstract.ts\";\n\nexport class CartDiscountService extends AbstractService {\n\tpublic repository: CartDiscountRepository;\n\n\tconstructor(parent: Router, repository: CartDiscountRepository) {\n\t\tsuper(parent);\n\t\tthis.repository = repository;\n\t}\n\n\tgetBasePath() {\n\t\treturn \"cart-discounts\";\n\t}\n}\n","import type { Router } from \"express\";\nimport type { CategoryRepository } from \"../repositories/category/index.ts\";\nimport AbstractService from \"./abstract.ts\";\n\nexport class CategoryServices extends AbstractService {\n\tpublic repository: CategoryRepository;\n\n\tconstructor(parent: Router, repository: CategoryRepository) {\n\t\tsuper(parent);\n\t\tthis.repository = repository;\n\t}\n\n\tgetBasePath() {\n\t\treturn \"categories\";\n\t}\n}\n","import type { Router } from \"express\";\nimport type { ChannelRepository } from \"../repositories/channel.ts\";\nimport AbstractService from \"./abstract.ts\";\n\nexport class ChannelService extends AbstractService {\n\tpublic repository: ChannelRepository;\n\n\tconstructor(parent: Router, repository: ChannelRepository) {\n\t\tsuper(parent);\n\t\tthis.repository = repository;\n\t}\n\n\tgetBasePath() {\n\t\treturn \"channels\";\n\t}\n}\n","import type { CustomObjectDraft } from \"@commercetools/platform-sdk\";\nimport type { Request, Response, Router } from \"express\";\nimport type { CustomObjectRepository } from \"../repositories/custom-object.ts\";\nimport { getRepositoryContext } from \"../repositories/helpers.ts\";\nimport AbstractService from \"./abstract.ts\";\n\nexport class CustomObjectService extends AbstractService {\n\tpublic repository: CustomObjectRepository;\n\n\tconstructor(parent: Router, repository: CustomObjectRepository) {\n\t\tsuper(parent);\n\t\tthis.repository = repository;\n\t}\n\n\tgetBasePath() {\n\t\treturn \"custom-objects\";\n\t}\n\n\textraRoutes(router: Router) {\n\t\trouter.get(\"/:container\", this.getWithContainer.bind(this));\n\t\trouter.get(\"/:container/:key\", this.getWithContainerAndKey.bind(this));\n\t\trouter.post(\"/:container/:key\", this.createWithContainerAndKey.bind(this));\n\t\trouter.delete(\n\t\t\t\"/:container/:key\",\n\t\t\tthis.deleteWithContainerAndKey.bind(this),\n\t\t);\n\t}\n\n\tgetWithContainer(request: Request, response: Response) {\n\t\tconst limit = this._parseParam(request.query.limit);\n\t\tconst offset = this._parseParam(request.query.offset);\n\n\t\tconst result = this.repository.queryWithContainer(\n\t\t\tgetRepositoryContext(request),\n\t\t\trequest.params.container,\n\t\t\t{\n\t\t\t\texpand: this._parseParam(request.query.expand),\n\t\t\t\twhere: this._parseParam(request.query.where),\n\t\t\t\tlimit: limit !== undefined ? Number(limit) : undefined,\n\t\t\t\toffset: offset !== undefined ? Number(offset) : undefined,\n\t\t\t},\n\t\t);\n\n\t\tresponse.status(200).send(result);\n\t}\n\n\tgetWithContainerAndKey(request: Request, response: Response) {\n\t\tconst result = this.repository.getWithContainerAndKey(\n\t\t\tgetRepositoryContext(request),\n\t\t\trequest.params.container,\n\t\t\trequest.params.key,\n\t\t);\n\n\t\tif (!result) {\n\t\t\tresponse.status(404).send({ statusCode: 404 });\n\t\t\treturn;\n\t\t}\n\t\tresponse.status(200).send(result);\n\t}\n\n\tcreateWithContainerAndKey(request: Request, response: Response) {\n\t\tconst draft: CustomObjectDraft = {\n\t\t\t...request.body,\n\t\t\tkey: request.params.key,\n\t\t\tcontainer: request.params.container,\n\t\t};\n\n\t\tconst result = this.repository.create(getRepositoryContext(request), draft);\n\t\tresponse.status(200).send(result);\n\t}\n\n\tdeleteWithContainerAndKey(request: Request, response: Response) {\n\t\tconst current = this.repository.getWithContainerAndKey(\n\t\t\tgetRepositoryContext(request),\n\t\t\trequest.params.container,\n\t\t\trequest.params.key,\n\t\t);\n\n\t\tif (!current) {\n\t\t\tresponse.status(404).send({ statusCode: 404 });\n\t\t\treturn;\n\t\t}\n\n\t\tconst result = this.repository.delete(\n\t\t\tgetRepositoryContext(request),\n\t\t\tcurrent.id,\n\t\t);\n\n\t\tresponse.status(200).send(result);\n\t}\n}\n","import type { CustomerSignInResult } from \"@commercetools/platform-sdk\";\nimport type { Request, Response, Router } from \"express\";\nimport type { CustomerRepository } from \"../repositories/customer/index.ts\";\nimport { getRepositoryContext } from \"../repositories/helpers.ts\";\nimport AbstractService from \"./abstract.ts\";\n\nexport class CustomerService extends AbstractService {\n\tpublic repository: CustomerRepository;\n\n\tconstructor(parent: Router, repository: CustomerRepository) {\n\t\tsuper(parent);\n\t\tthis.repository = repository;\n\t}\n\n\tgetBasePath() {\n\t\treturn \"customers\";\n\t}\n\n\textraRoutes(parent: Router) {\n\t\tparent.post(\"/password-token\", this.passwordResetToken.bind(this));\n\t\tparent.post(\"/password/reset\", this.passwordReset.bind(this));\n\t\tparent.post(\"/email-token\", this.confirmEmailToken.bind(this));\n\t}\n\n\tpost(request: Request, response: Response) {\n\t\tconst draft = request.body;\n\t\tconst resource = this.repository.create(\n\t\t\tgetRepositoryContext(request),\n\t\t\tdraft,\n\t\t);\n\t\tconst expanded = this._expandWithId(request, resource.id);\n\n\t\tconst result: CustomerSignInResult = {\n\t\t\tcustomer: expanded,\n\t\t};\n\t\tresponse.status(this.createStatusCode).send(result);\n\t}\n\n\tpasswordResetToken(request: Request, response: Response) {\n\t\tconst customer = this.repository.passwordResetToken(\n\t\t\tgetRepositoryContext(request),\n\t\t\trequest.body,\n\t\t);\n\n\t\tresponse.status(200).send(customer);\n\t}\n\n\tpasswordReset(request: Request, response: Response) {\n\t\tconst customer = this.repository.passwordReset(\n\t\t\tgetRepositoryContext(request),\n\t\t\trequest.body,\n\t\t);\n\n\t\tresponse.status(200).send(customer);\n\t}\n\n\tconfirmEmailToken(request: Request, response: Response) {\n\t\tconst id = request.body.id;\n\t\tconst token = this.repository.verifyEmailToken(\n\t\t\tgetRepositoryContext(request),\n\t\t\tid,\n\t\t);\n\t\tresponse.status(200).send(token);\n\t}\n}\n","import type { Router } from \"express\";\nimport type { CustomerGroupRepository } from \"../repositories/customer-group.ts\";\nimport AbstractService from \"./abstract.ts\";\n\nexport class CustomerGroupService extends AbstractService {\n\tpublic repository: CustomerGroupRepository;\n\n\tconstructor(parent: Router, repository: CustomerGroupRepository) {\n\t\tsuper(parent);\n\t\tthis.repository = repository;\n\t}\n\n\tgetBasePath() {\n\t\treturn \"customer-groups\";\n\t}\n}\n","import type { Router } from \"express\";\nimport type { DiscountCodeRepository } from \"../repositories/discount-code/index.ts\";\nimport AbstractService from \"./abstract.ts\";\n\nexport class DiscountCodeService extends AbstractService {\n\tpublic repository: DiscountCodeRepository;\n\n\tconstructor(parent: Router, repository: DiscountCodeRepository) {\n\t\tsuper(parent);\n\t\tthis.repository = repository;\n\t}\n\n\tgetBasePath() {\n\t\treturn \"discount-codes\";\n\t}\n}\n","import type { Router } from \"express\";\nimport type { DiscountGroupRepository } from \"../repositories/discount-group/index.ts\";\nimport AbstractService from \"./abstract.ts\";\n\nexport class DiscountGroupService extends AbstractService {\n\tpublic repository: DiscountGroupRepository;\n\n\tconstructor(parent: Router, repository: DiscountGroupRepository) {\n\t\tsuper(parent);\n\t\tthis.repository = repository;\n\t}\n\n\tgetBasePath() {\n\t\treturn \"discount-groups\";\n\t}\n}\n","import type { Router } from \"express\";\nimport type { ExtensionRepository } from \"../repositories/extension.ts\";\nimport AbstractService from \"./abstract.ts\";\n\nexport class ExtensionServices extends AbstractService {\n\tpublic repository: ExtensionRepository;\n\n\tconstructor(parent: Router, repository: ExtensionRepository) {\n\t\tsuper(parent);\n\t\tthis.repository = repository;\n\t}\n\n\tgetBasePath() {\n\t\treturn \"extensions\";\n\t}\n}\n","import type { Router } from \"express\";\nimport type { InventoryEntryRepository } from \"../repositories/inventory-entry/index.ts\";\nimport AbstractService from \"./abstract.ts\";\n\nexport class InventoryEntryService extends AbstractService {\n\tpublic repository: InventoryEntryRepository;\n\n\tconstructor(parent: Router, repository: InventoryEntryRepository) {\n\t\tsuper(parent);\n\t\tthis.repository = repository;\n\t}\n\n\tgetBasePath() {\n\t\treturn \"inventory\";\n\t}\n}\n","import { Router } from \"express\";\nimport type { BusinessUnitRepository } from \"#src/repositories/business-unit.ts\";\nimport AbstractService from \"./abstract.ts\";\n\nexport class MyBusinessUnitService extends AbstractService {\n\tpublic repository: BusinessUnitRepository;\n\n\tconstructor(parent: Router, repository: BusinessUnitRepository) {\n\t\tsuper(parent);\n\t\tthis.repository = repository;\n\t}\n\n\tgetBasePath() {\n\t\treturn \"me\";\n\t}\n\n\tregisterRoutes(parent: Router) {\n\t\t// Overwrite this function to be able to handle /me/business-units path.\n\t\tconst basePath = this.getBasePath();\n\t\tconst router = Router({ mergeParams: true });\n\n\t\tthis.extraRoutes(router);\n\n\t\trouter.get(\"/business-units/\", this.get.bind(this));\n\t\trouter.get(\"/business-units/key=:key\", this.getWithKey.bind(this));\n\t\trouter.get(\"/business-units/:id\", this.getWithId.bind(this));\n\n\t\trouter.delete(\"/business-units/key=:key\", this.deleteWithKey.bind(this));\n\t\trouter.delete(\"/business-units/:id\", this.deleteWithId.bind(this));\n\n\t\trouter.post(\"/business-units/\", this.post.bind(this));\n\t\trouter.post(\"/business-units/key=:key\", this.postWithKey.bind(this));\n\t\trouter.post(\"/business-units/:id\", this.postWithId.bind(this));\n\n\t\tparent.use(`/${basePath}`, router);\n\t}\n}\n","import type { Request, Response } from \"express\";\nimport { Router } from \"express\";\nimport type { CartRepository } from \"../repositories/cart/index.ts\";\nimport AbstractService from \"./abstract.ts\";\n\nexport class MyCartService extends AbstractService {\n\tpublic repository: CartRepository;\n\n\tconstructor(parent: Router, repository: CartRepository) {\n\t\tsuper(parent);\n\t\tthis.repository = repository;\n\t}\n\n\tgetBasePath() {\n\t\treturn \"me\";\n\t}\n\n\tregisterRoutes(parent: Router) {\n\t\t// Overwrite this function to be able to handle /me/active-cart path.\n\t\tconst basePath = this.getBasePath();\n\t\tconst router = Router({ mergeParams: true });\n\n\t\tthis.extraRoutes(router);\n\n\t\trouter.get(\"/active-cart\", this.activeCart.bind(this));\n\t\trouter.get(\"/carts/\", this.get.bind(this));\n\t\trouter.get(\"/carts/:id\", this.getWithId.bind(this));\n\n\t\trouter.delete(\"/carts/:id\", this.deleteWithId.bind(this));\n\n\t\trouter.post(\"/carts/\", this.post.bind(this));\n\t\trouter.post(\"/carts/:id\", this.postWithId.bind(this));\n\n\t\tparent.use(`/${basePath}`, router);\n\t}\n\n\tactiveCart(request: Request, response: Response) {\n\t\tconst resource = this.repository.getActiveCart(request.params.projectKey);\n\t\tif (!resource) {\n\t\t\tresponse.status(404).send({\n\t\t\t\tstatusCode: 404,\n\t\t\t\tmessage: \"No active cart exists.\",\n\t\t\t\terrors: [\n\t\t\t\t\t{\n\t\t\t\t\t\tcode: \"ResourceNotFound\",\n\t\t\t\t\t\tmessage: \"No active cart exists.\",\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\t\tresponse.status(200).send(resource);\n\t}\n}\n","import type { Update } from \"@commercetools/platform-sdk\";\nimport type { Request, Response } from \"express\";\nimport { Router } from \"express\";\nimport { updateRequestSchema } from \"#src/schemas/update-request.ts\";\nimport { validateData } from \"#src/validate.ts\";\nimport { hashPassword } from \"../lib/password.ts\";\nimport { getRepositoryContext } from \"../repositories/helpers.ts\";\nimport type { MyCustomerRepository } from \"../repositories/my-customer.ts\";\nimport AbstractService from \"./abstract.ts\";\n\nexport class MyCustomerService extends AbstractService {\n\tpublic repository: MyCustomerRepository;\n\n\tconstructor(parent: Router, repository: MyCustomerRepository) {\n\t\tsuper(parent);\n\t\tthis.repository = repository;\n\t}\n\n\tgetBasePath() {\n\t\treturn \"me\";\n\t}\n\n\tregisterRoutes(parent: Router) {\n\t\t// Overwrite this function to be able to handle /me path.\n\t\tconst basePath = this.getBasePath();\n\t\tconst router = Router({ mergeParams: true });\n\n\t\tthis.extraRoutes(router);\n\n\t\trouter.get(\"\", this.getMe.bind(this));\n\t\trouter.post(\"\", this.updateMe.bind(this));\n\t\trouter.delete(\"\", this.deleteMe.bind(this));\n\n\t\trouter.post(\"/signup\", this.signUp.bind(this));\n\n\t\trouter.post(\"/login\", this.signIn.bind(this));\n\t\trouter.post(\"/password\", this.changePassword.bind(this));\n\t\trouter.post(\"/password/reset\", this.resetPassword.bind(this));\n\t\trouter.post(\"/email/confirm\", this.emailConfirm.bind(this));\n\n\t\tparent.use(`/${basePath}`, router);\n\t}\n\n\tgetMe(request: Request, response: Response) {\n\t\tconst resource = this.repository.getMe(getRepositoryContext(request));\n\t\tif (!resource) {\n\t\t\tresponse.status(404).send({ statusCode: 404 });\n\t\t\treturn;\n\t\t}\n\t\tresponse.status(200).send(resource);\n\t}\n\n\tupdateMe(request: Request, response: Response) {\n\t\tconst resource = this.repository.getMe(getRepositoryContext(request));\n\n\t\tif (!resource) {\n\t\t\tresponse.status(404).send({ statusCode: 404 });\n\t\t\treturn;\n\t\t}\n\t\tconst updateRequest = validateData<Update>(\n\t\t\trequest.body,\n\t\t\tupdateRequestSchema,\n\t\t);\n\t\tconst updatedResource = this.repository.processUpdateActions(\n\t\t\tgetRepositoryContext(request),\n\t\t\tresource,\n\t\t\tupdateRequest.version,\n\t\t\tupdateRequest.actions,\n\t\t);\n\n\t\tconst result = this._expandWithId(request, updatedResource.id);\n\t\tresponse.status(200).send(result);\n\t}\n\n\tdeleteMe(request: Request, response: Response) {\n\t\tconst resource = this.repository.deleteMe(getRepositoryContext(request));\n\t\tif (!resource) {\n\t\t\tresponse.status(404).send({ statusCode: 404 });\n\t\t\treturn;\n\t\t}\n\n\t\tresponse.status(200).send(resource);\n\t}\n\n\tsignUp(request: Request, response: Response) {\n\t\tconst draft = request.body;\n\t\tconst resource = this.repository.create(\n\t\t\tgetRepositoryContext(request),\n\t\t\tdraft,\n\t\t);\n\t\tconst result = this._expandWithId(request, resource.id);\n\t\tresponse.status(this.createStatusCode).send({ customer: result });\n\t}\n\n\tchangePassword(request: Request, response: Response) {\n\t\tconst customer = this.repository.changePassword(\n\t\t\tgetRepositoryContext(request),\n\t\t\trequest.body,\n\t\t);\n\n\t\tresponse.status(200).send(customer);\n\t}\n\n\tresetPassword(request: Request, response: Response) {\n\t\tconst customer = this.repository.passwordReset(\n\t\t\tgetRepositoryContext(request),\n\t\t\trequest.body,\n\t\t);\n\n\t\tresponse.status(200).send(customer);\n\t}\n\n\temailConfirm(request: Request, response: Response) {\n\t\tconst customer = this.repository.confirmEmail(\n\t\t\tgetRepositoryContext(request),\n\t\t\trequest.body,\n\t\t);\n\n\t\tresponse.status(200).send(customer);\n\t}\n\n\tsignIn(request: Request, response: Response) {\n\t\tconst { email, password } = request.body;\n\t\tconst encodedPassword = hashPassword(password);\n\n\t\tconst result = this.repository.query(getRepositoryContext(request), {\n\t\t\twhere: [`email = \"${email}\"`, `password = \"${encodedPassword}\"`],\n\t\t});\n\n\t\tif (result.count === 0) {\n\t\t\tresponse.status(400).send({\n\t\t\t\tmessage: \"Account with the given credentials not found.\",\n\t\t\t\terrors: [\n\t\t\t\t\t{\n\t\t\t\t\t\tcode: \"InvalidCredentials\",\n\t\t\t\t\t\tmessage: \"Account with the given credentials not found.\",\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\n\t\tresponse.status(200).send({ customer: result.results[0] });\n\t}\n}\n","import { Router } from \"express\";\nimport type { MyOrderRepository } from \"../repositories/my-order.ts\";\nimport AbstractService from \"./abstract.ts\";\n\nexport class MyOrderService extends AbstractService {\n\tpublic repository: MyOrderRepository;\n\n\tconstructor(parent: Router, repository: MyOrderRepository) {\n\t\tsuper(parent);\n\t\tthis.repository = repository;\n\t}\n\n\tgetBasePath() {\n\t\treturn \"me\";\n\t}\n\n\tregisterRoutes(parent: Router) {\n\t\t// Overwrite this function to be able to handle /me/active-cart path.\n\t\tconst basePath = this.getBasePath();\n\t\tconst router = Router({ mergeParams: true });\n\n\t\tthis.extraRoutes(router);\n\n\t\trouter.get(\"/orders/\", this.get.bind(this));\n\t\trouter.get(\"/orders/:id\", this.getWithId.bind(this));\n\n\t\trouter.delete(\"/orders/:id\", this.deleteWithId.bind(this));\n\n\t\trouter.post(\"/orders/\", this.post.bind(this));\n\t\trouter.post(\"/orders/:id\", this.postWithId.bind(this));\n\n\t\tparent.use(`/${basePath}`, router);\n\t}\n}\n","import type { Router } from \"express\";\nimport type { PaymentRepository } from \"../repositories/payment/index.ts\";\nimport AbstractService from \"./abstract.ts\";\n\nexport class MyPaymentService extends AbstractService {\n\tpublic repository: PaymentRepository;\n\n\tconstructor(parent: Router, repository: PaymentRepository) {\n\t\tsuper(parent);\n\t\tthis.repository = repository;\n\t}\n\n\tgetBasePath() {\n\t\treturn \"me/payments\";\n\t}\n}\n","import type { Router } from \"express\";\nimport type { ShoppingListRepository } from \"../repositories/shopping-list/index.ts\";\nimport AbstractService from \"./abstract.ts\";\n\nexport class MyShoppingListService extends AbstractService {\n\tpublic repository: ShoppingListRepository;\n\n\tconstructor(parent: Router, repository: ShoppingListRepository) {\n\t\tsuper(parent);\n\t\tthis.repository = repository;\n\t}\n\n\tgetBasePath() {\n\t\treturn \"me/shopping-lists\";\n\t}\n}\n","import type { Request, Response, Router } from \"express\";\nimport { getRepositoryContext } from \"../repositories/helpers.ts\";\nimport type { OrderRepository } from \"../repositories/order/index.ts\";\nimport AbstractService from \"./abstract.ts\";\n\nexport class OrderService extends AbstractService {\n\tpublic repository: OrderRepository;\n\n\tconstructor(parent: Router, repository: OrderRepository) {\n\t\tsuper(parent);\n\t\tthis.repository = repository;\n\t}\n\n\tgetBasePath() {\n\t\treturn \"orders\";\n\t}\n\n\textraRoutes(router: Router) {\n\t\trouter.post(\"/import\", this.import.bind(this));\n\t\trouter.get(\n\t\t\t\"/order-number=:orderNumber\",\n\t\t\tthis.getWithOrderNumber.bind(this),\n\t\t);\n\t}\n\n\timport(request: Request, response: Response) {\n\t\tconst importDraft = request.body;\n\t\tconst resource = this.repository.import(\n\t\t\tgetRepositoryContext(request),\n\t\t\timportDraft,\n\t\t);\n\t\tresponse.status(200).send(resource);\n\t}\n\n\tgetWithOrderNumber(request: Request, response: Response) {\n\t\tconst orderNumber = request.params.orderNumber;\n\t\tconst resource = this.repository.getWithOrderNumber(\n\t\t\tgetRepositoryContext(request),\n\t\t\torderNumber,\n\n\t\t\t// @ts-expect-error\n\t\t\trequest.query,\n\t\t);\n\t\tif (resource) {\n\t\t\tresponse.status(200).send(resource);\n\t\t\treturn;\n\t\t}\n\t\tresponse.status(404).send({\n\t\t\tstatusCode: 404,\n\t\t\tmessage: `The Resource with key '${orderNumber}' was not found.`,\n\t\t\terrors: [\n\t\t\t\t{\n\t\t\t\t\tcode: \"ResourceNotFound\",\n\t\t\t\t\tmessage: `The Resource with key '${orderNumber}' was not found.`,\n\t\t\t\t},\n\t\t\t],\n\t\t});\n\t}\n}\n","import type { Router } from \"express\";\nimport type { PaymentRepository } from \"../repositories/payment/index.ts\";\nimport AbstractService from \"./abstract.ts\";\n\nexport class PaymentService extends AbstractService {\n\tpublic repository: PaymentRepository;\n\n\tconstructor(parent: Router, repository: PaymentRepository) {\n\t\tsuper(parent);\n\t\tthis.repository = repository;\n\t}\n\n\tgetBasePath() {\n\t\treturn \"payments\";\n\t}\n}\n","import type { Request, Response, Router } from \"express\";\nimport { getRepositoryContext } from \"#src/repositories/helpers.ts\";\nimport type { ProductRepository } from \"../repositories/product/index.ts\";\nimport AbstractService from \"./abstract.ts\";\n\nexport class ProductService extends AbstractService {\n\tpublic repository: ProductRepository;\n\n\tconstructor(parent: Router, repository: ProductRepository) {\n\t\tsuper(parent);\n\t\tthis.repository = repository;\n\t}\n\n\tgetBasePath() {\n\t\treturn \"products\";\n\t}\n\n\textraRoutes(router: Router) {\n\t\trouter.post(\"/search\", this.search.bind(this));\n\t}\n\n\tsearch(request: Request, response: Response) {\n\t\tconst searchBody = request.body;\n\t\tconst resource = this.repository.search(\n\t\t\tgetRepositoryContext(request),\n\t\t\tsearchBody,\n\t\t);\n\t\tresponse.status(200).send(resource);\n\t}\n}\n","import type { Router } from \"express\";\nimport type { ProductDiscountRepository } from \"../repositories/product-discount.ts\";\nimport AbstractService from \"./abstract.ts\";\n\nexport class ProductDiscountService extends AbstractService {\n\tpublic repository: ProductDiscountRepository;\n\n\tconstructor(parent: Router, repository: ProductDiscountRepository) {\n\t\tsuper(parent);\n\t\tthis.repository = repository;\n\t}\n\n\tgetBasePath() {\n\t\treturn \"product-discounts\";\n\t}\n}\n","import type { Request, Response, Router } from \"express\";\nimport { queryParamsArray, queryParamsValue } from \"../helpers.ts\";\nimport { getRepositoryContext } from \"../repositories/helpers.ts\";\nimport type {\n\tProductProjectionQueryParams,\n\tProductProjectionRepository,\n} from \"./../repositories/product-projection.ts\";\nimport AbstractService from \"./abstract.ts\";\n\nexport class ProductProjectionService extends AbstractService {\n\tpublic repository: ProductProjectionRepository;\n\n\tconstructor(parent: Router, repository: ProductProjectionRepository) {\n\t\tsuper(parent);\n\t\tthis.repository = repository;\n\t}\n\n\tgetBasePath() {\n\t\treturn \"product-projections\";\n\t}\n\n\textraRoutes(router: Router) {\n\t\trouter.get(\"/search\", this.search.bind(this));\n\t}\n\n\tget(request: Request, response: Response) {\n\t\tconst limit = this._parseParam(request.query.limit);\n\t\tconst offset = this._parseParam(request.query.offset);\n\n\t\tconst result = this.repository.query(getRepositoryContext(request), {\n\t\t\t...request.query,\n\t\t\texpand: this._parseParam(request.query.expand),\n\t\t\twhere: this._parseParam(request.query.where),\n\t\t\tlimit: limit !== undefined ? Number(limit) : undefined,\n\t\t\toffset: offset !== undefined ? Number(offset) : undefined,\n\t\t});\n\t\tresponse.status(200).send(result);\n\t}\n\n\tsearch(request: Request, response: Response) {\n\t\tconst query = request.query;\n\t\tconst searchParams: ProductProjectionQueryParams = {\n\t\t\tfilter: queryParamsArray(query.filter),\n\t\t\t\"filter.query\": queryParamsArray(query[\"filter.query\"]),\n\t\t\tfacet: queryParamsArray(query.facet),\n\t\t\texpand: queryParamsArray(query.expand),\n\t\t\tstaged: queryParamsValue(query.staged) === \"true\",\n\t\t\tlocaleProjection: queryParamsValue(query.localeProjection),\n\t\t\tstoreProjection: queryParamsValue(query.storeProjection),\n\t\t\tpriceChannel: queryParamsValue(query.priceChannel),\n\t\t\tpriceCountry: queryParamsValue(query.priceCountry),\n\t\t\tpriceCurrency: queryParamsValue(query.priceCurrency),\n\t\t\tpriceCustomerGroup: queryParamsValue(query.priceCustomerGroup),\n\t\t\toffset: query.offset ? Number(queryParamsValue(query.offset)) : undefined,\n\t\t\tlimit: query.limit ? Number(queryParamsValue(query.limit)) : undefined,\n\t\t};\n\t\tconst resource = this.repository.search(\n\t\t\tgetRepositoryContext(request),\n\t\t\tsearchParams,\n\t\t);\n\t\tresponse.status(200).send(resource);\n\t}\n}\n","import type { Router } from \"express\";\nimport type { ProductSelectionRepository } from \"../repositories/product-selection.ts\";\nimport AbstractService from \"./abstract.ts\";\n\nexport class ProductSelectionService extends AbstractService {\n\tpublic repository: ProductSelectionRepository;\n\n\tconstructor(parent: Router, repository: ProductSelectionRepository) {\n\t\tsuper(parent);\n\t\tthis.repository = repository;\n\t}\n\n\tgetBasePath() {\n\t\treturn \"product-selections\";\n\t}\n}\n","import type { Router } from \"express\";\nimport type { ProductTypeRepository } from \"../repositories/product-type.ts\";\nimport AbstractService from \"./abstract.ts\";\n\nexport class ProductTypeService extends AbstractService {\n\tpublic repository: ProductTypeRepository;\n\n\tconstructor(parent: Router, repository: ProductTypeRepository) {\n\t\tsuper(parent);\n\t\tthis.repository = repository;\n\t}\n\n\tgetBasePath() {\n\t\treturn \"product-types\";\n\t}\n}\n","import type { Router } from \"express\";\nimport type { QuoteRepository } from \"#src/repositories/quote/index.ts\";\nimport AbstractService from \"./abstract.ts\";\n\nexport class QuoteService extends AbstractService {\n\tpublic repository: QuoteRepository;\n\n\tconstructor(parent: Router, repository: QuoteRepository) {\n\t\tsuper(parent);\n\t\tthis.repository = repository;\n\t}\n\n\tgetBasePath() {\n\t\treturn \"quotes\";\n\t}\n}\n","import type { Router } from \"express\";\nimport type { QuoteRequestRepository } from \"#src/repositories/quote-request/index.ts\";\nimport AbstractService from \"./abstract.ts\";\n\nexport class QuoteRequestService extends AbstractService {\n\tpublic repository: QuoteRequestRepository;\n\n\tconstructor(parent: Router, repository: QuoteRequestRepository) {\n\t\tsuper(parent);\n\t\tthis.repository = repository;\n\t}\n\n\tgetBasePath() {\n\t\treturn \"quote-requests\";\n\t}\n}\n","import type { Router } from \"express\";\nimport type { StagedQuoteRepository } from \"#src/repositories/quote-staged/index.ts\";\nimport AbstractService from \"./abstract.ts\";\n\nexport class StagedQuoteService extends AbstractService {\n\tpublic repository: StagedQuoteRepository;\n\n\tconstructor(parent: Router, repository: StagedQuoteRepository) {\n\t\tsuper(parent);\n\t\tthis.repository = repository;\n\t}\n\n\tgetBasePath() {\n\t\treturn \"staged-quotes\";\n\t}\n}\n","import type { Router } from \"express\";\nimport type { RecurrencePolicyRepository } from \"../repositories/recurrence-policy/index.ts\";\nimport AbstractService from \"./abstract.ts\";\n\nexport class RecurrencePolicyService extends AbstractService {\n\tpublic repository: RecurrencePolicyRepository;\n\n\tconstructor(parent: Router, repository: RecurrencePolicyRepository) {\n\t\tsuper(parent);\n\t\tthis.repository = repository;\n\t}\n\n\tgetBasePath() {\n\t\treturn \"recurrence-policies\";\n\t}\n}\n","import type { Router } from \"express\";\nimport type { RecurringOrderRepository } from \"../repositories/recurring-order/index.ts\";\nimport AbstractService from \"./abstract.ts\";\n\nexport class RecurringOrderService extends AbstractService {\n\tpublic repository: RecurringOrderRepository;\n\n\tconstructor(parent: Router, repository: RecurringOrderRepository) {\n\t\tsuper(parent);\n\t\tthis.repository = repository;\n\t}\n\n\tgetBasePath() {\n\t\treturn \"recurring-orders\";\n\t}\n}\n","import type { Router } from \"express\";\nimport type { ReviewRepository } from \"../repositories/review.ts\";\nimport AbstractService from \"./abstract.ts\";\n\nexport class ReviewService extends AbstractService {\n\tpublic repository: ReviewRepository;\n\n\tconstructor(parent: Router, repository: ReviewRepository) {\n\t\tsuper(parent);\n\t\tthis.repository = repository;\n\t}\n\n\tgetBasePath() {\n\t\treturn \"reviews\";\n\t}\n}\n","import type { Request, Response, Router } from \"express\";\nimport { queryParamsValue } from \"../helpers.ts\";\nimport { getRepositoryContext } from \"../repositories/helpers.ts\";\nimport type { ShippingMethodRepository } from \"../repositories/shipping-method/index.ts\";\nimport AbstractService from \"./abstract.ts\";\n\nexport class ShippingMethodService extends AbstractService {\n\tpublic repository: ShippingMethodRepository;\n\n\tconstructor(parent: Router, repository: ShippingMethodRepository) {\n\t\tsuper(parent);\n\t\tthis.repository = repository;\n\t\tthis.registerRoutes(parent);\n\t}\n\n\tgetBasePath() {\n\t\treturn \"shipping-methods\";\n\t}\n\n\textraRoutes(parent: Router) {\n\t\tparent.get(\"/matching-cart\", this.matchingCart.bind(this));\n\t}\n\n\tmatchingCart(request: Request, response: Response) {\n\t\tconst cartId = queryParamsValue(request.query.cartId);\n\t\tif (!cartId) {\n\t\t\tresponse.status(400).send();\n\t\t\treturn;\n\t\t}\n\t\tconst result = this.repository.matchingCart(\n\t\t\tgetRepositoryContext(request),\n\t\t\tcartId,\n\t\t\t{\n\t\t\t\texpand: this._parseParam(request.query.expand),\n\t\t\t},\n\t\t);\n\t\tresponse.status(200).send(result);\n\t\treturn;\n\t}\n}\n","import type { Router } from \"express\";\nimport type { ShoppingListRepository } from \"../repositories/shopping-list/index.ts\";\nimport AbstractService from \"./abstract.ts\";\n\nexport class ShoppingListService extends AbstractService {\n\tpublic repository: ShoppingListRepository;\n\n\tconstructor(parent: Router, repository: ShoppingListRepository) {\n\t\tsuper(parent);\n\t\tthis.repository = repository;\n\t}\n\n\tgetBasePath() {\n\t\treturn \"shopping-lists\";\n\t}\n}\n","import type { Router } from \"express\";\nimport type { StandAlonePriceRepository } from \"../repositories/standalone-price.ts\";\nimport AbstractService from \"./abstract.ts\";\n\nexport class StandAlonePriceService extends AbstractService {\n\tpublic repository: StandAlonePriceRepository;\n\n\tconstructor(parent: Router, repository: StandAlonePriceRepository) {\n\t\tsuper(parent);\n\t\tthis.repository = repository;\n\t}\n\n\tgetBasePath() {\n\t\treturn \"standalone-prices\";\n\t}\n}\n","import type { Router } from \"express\";\nimport type { StateRepository } from \"../repositories/state.ts\";\nimport AbstractService from \"./abstract.ts\";\n\nexport class StateService extends AbstractService {\n\tpublic repository: StateRepository;\n\n\tconstructor(parent: Router, repository: StateRepository) {\n\t\tsuper(parent);\n\t\tthis.repository = repository;\n\t}\n\n\tgetBasePath() {\n\t\treturn \"states\";\n\t}\n}\n","import type { Router } from \"express\";\nimport type { StoreRepository } from \"../repositories/store.ts\";\nimport AbstractService from \"./abstract.ts\";\n\nexport class StoreService extends AbstractService {\n\tpublic repository: StoreRepository;\n\n\tconstructor(parent: Router, repository: StoreRepository) {\n\t\tsuper(parent);\n\t\tthis.repository = repository;\n\t}\n\n\tgetBasePath() {\n\t\treturn \"stores\";\n\t}\n}\n","import type { Router } from \"express\";\nimport type { SubscriptionRepository } from \"../repositories/subscription.ts\";\nimport AbstractService from \"./abstract.ts\";\n\nexport class SubscriptionService extends AbstractService {\n\tpublic repository: SubscriptionRepository;\n\n\tconstructor(parent: Router, repository: SubscriptionRepository) {\n\t\tsuper(parent);\n\t\tthis.repository = repository;\n\t}\n\n\tgetBasePath() {\n\t\treturn \"subscriptions\";\n\t}\n}\n","import type { Router } from \"express\";\nimport type { TaxCategoryRepository } from \"../repositories/tax-category/index.ts\";\nimport AbstractService from \"./abstract.ts\";\n\nexport class TaxCategoryService extends AbstractService {\n\tpublic repository: TaxCategoryRepository;\n\n\tconstructor(parent: Router, repository: TaxCategoryRepository) {\n\t\tsuper(parent);\n\t\tthis.repository = repository;\n\t}\n\n\tgetBasePath() {\n\t\treturn \"tax-categories\";\n\t}\n}\n","import type { Router } from \"express\";\nimport type { TypeRepository } from \"../repositories/type/index.ts\";\nimport AbstractService from \"./abstract.ts\";\n\nexport class TypeService extends AbstractService {\n\tpublic repository: TypeRepository;\n\n\tconstructor(parent: Router, repository: TypeRepository) {\n\t\tsuper(parent);\n\t\tthis.repository = repository;\n\t}\n\n\tgetBasePath() {\n\t\treturn \"types\";\n\t}\n}\n","import type { Router } from \"express\";\nimport type { ZoneRepository } from \"../repositories/zone.ts\";\nimport AbstractService from \"./abstract.ts\";\n\nexport class ZoneService extends AbstractService {\n\tpublic repository: ZoneRepository;\n\n\tconstructor(parent: Router, repository: ZoneRepository) {\n\t\tsuper(parent);\n\t\tthis.repository = repository;\n\t}\n\n\tgetBasePath() {\n\t\treturn \"zones\";\n\t}\n}\n","import type { createRepositories } from \"../repositories/index.ts\";\nimport { AsAssociateService } from \"./as-associate.ts\";\nimport { AssociateRoleServices } from \"./associate-roles.ts\";\nimport { AttributeGroupService } from \"./attribute-group.ts\";\nimport { BusinessUnitServices } from \"./business-units.ts\";\nimport { CartService } from \"./cart.ts\";\nimport { CartDiscountService } from \"./cart-discount.ts\";\nimport { CategoryServices } from \"./category.ts\";\nimport { ChannelService } from \"./channel.ts\";\nimport { CustomObjectService } from \"./custom-object.ts\";\nimport { CustomerService } from \"./customer.ts\";\nimport { CustomerGroupService } from \"./customer-group.ts\";\nimport { DiscountCodeService } from \"./discount-code.ts\";\nimport { DiscountGroupService } from \"./discount-group.ts\";\nimport { ExtensionServices } from \"./extension.ts\";\nimport { InventoryEntryService } from \"./inventory-entry.ts\";\nimport { MyBusinessUnitService } from \"./my-business-unit.ts\";\nimport { MyCartService } from \"./my-cart.ts\";\nimport { MyCustomerService } from \"./my-customer.ts\";\nimport { MyOrderService } from \"./my-order.ts\";\nimport { MyPaymentService } from \"./my-payment.ts\";\nimport { MyShoppingListService } from \"./my-shopping-list.ts\";\nimport { OrderService } from \"./order.ts\";\nimport { PaymentService } from \"./payment.ts\";\nimport { ProductService } from \"./product.ts\";\nimport { ProductDiscountService } from \"./product-discount.ts\";\nimport { ProductProjectionService } from \"./product-projection.ts\";\nimport { ProductSelectionService } from \"./product-selection.ts\";\nimport { ProductTypeService } from \"./product-type.ts\";\nimport { QuoteService } from \"./quote.ts\";\nimport { QuoteRequestService } from \"./quote-request.ts\";\nimport { StagedQuoteService } from \"./quote-staged.ts\";\nimport { RecurrencePolicyService } from \"./recurrence-policy.ts\";\nimport { RecurringOrderService } from \"./recurring-order.ts\";\nimport { ReviewService } from \"./reviews.ts\";\nimport { ShippingMethodService } from \"./shipping-method.ts\";\nimport { ShoppingListService } from \"./shopping-list.ts\";\nimport { StandAlonePriceService } from \"./standalone-price.ts\";\nimport { StateService } from \"./state.ts\";\nimport { StoreService } from \"./store.ts\";\nimport { SubscriptionService } from \"./subscription.ts\";\nimport { TaxCategoryService } from \"./tax-category.ts\";\nimport { TypeService } from \"./type.ts\";\nimport { ZoneService } from \"./zone.ts\";\n\nexport const createServices = (\n\trouter: any,\n\trepos: ReturnType<typeof createRepositories>,\n) => ({\n\t\"associate-role\": new AssociateRoleServices(router, repos[\"associate-role\"]),\n\t\"as-associate\": new AsAssociateService(router, repos[\"as-associate\"]),\n\t\"business-unit\": new BusinessUnitServices(router, repos[\"business-unit\"]),\n\tcategory: new CategoryServices(router, repos.category),\n\tcart: new CartService(router, repos.cart, repos.order),\n\t\"cart-discount\": new CartDiscountService(router, repos[\"cart-discount\"]),\n\tcustomer: new CustomerService(router, repos.customer),\n\tchannel: new ChannelService(router, repos.channel),\n\t\"customer-group\": new CustomerGroupService(router, repos[\"customer-group\"]),\n\t\"discount-code\": new DiscountCodeService(router, repos[\"discount-code\"]),\n\t\"discount-group\": new DiscountGroupService(router, repos[\"discount-group\"]),\n\textension: new ExtensionServices(router, repos.extension),\n\t\"inventory-entry\": new InventoryEntryService(\n\t\trouter,\n\t\trepos[\"inventory-entry\"],\n\t),\n\t\"key-value-document\": new CustomObjectService(\n\t\trouter,\n\t\trepos[\"key-value-document\"],\n\t),\n\torder: new OrderService(router, repos.order),\n\tpayment: new PaymentService(router, repos.payment),\n\t\"standalone-price\": new StandAlonePriceService(\n\t\trouter,\n\t\trepos[\"standalone-price\"],\n\t),\n\t\"my-cart\": new MyCartService(router, repos[\"my-cart\"]),\n\t\"my-order\": new MyOrderService(router, repos[\"my-order\"]),\n\t\"my-customer\": new MyCustomerService(router, repos[\"my-customer\"]),\n\t\"my-business-unit\": new MyBusinessUnitService(router, repos[\"business-unit\"]),\n\t\"my-payment\": new MyPaymentService(router, repos[\"my-payment\"]),\n\t\"my-shopping-list\": new MyShoppingListService(\n\t\trouter,\n\t\trepos[\"my-shopping-list\"],\n\t),\n\t\"shipping-method\": new ShippingMethodService(\n\t\trouter,\n\t\trepos[\"shipping-method\"],\n\t),\n\t\"product-type\": new ProductTypeService(router, repos[\"product-type\"]),\n\tproduct: new ProductService(router, repos.product),\n\t\"product-discount\": new ProductDiscountService(\n\t\trouter,\n\t\trepos[\"product-discount\"],\n\t),\n\t\"product-projection\": new ProductProjectionService(\n\t\trouter,\n\t\trepos[\"product-projection\"],\n\t),\n\t\"product-selection\": new ProductSelectionService(\n\t\trouter,\n\t\trepos[\"product-selection\"],\n\t),\n\tquotes: new QuoteService(router, repos.quote),\n\t\"quote-request\": new QuoteRequestService(router, repos[\"quote-request\"]),\n\t\"recurrence-policy\": new RecurrencePolicyService(\n\t\trouter,\n\t\trepos[\"recurrence-policy\"],\n\t),\n\t\"recurring-order\": new RecurringOrderService(\n\t\trouter,\n\t\trepos[\"recurring-order\"],\n\t),\n\treviews: new ReviewService(router, repos.review),\n\t\"shopping-list\": new ShoppingListService(router, repos[\"shopping-list\"]),\n\t\"staged-quote\": new StagedQuoteService(router, repos[\"staged-quote\"]),\n\tstate: new StateService(router, repos.state),\n\tstore: new StoreService(router, repos.store),\n\tsubscription: new SubscriptionService(router, repos.subscription),\n\t\"tax-category\": new TaxCategoryService(router, repos[\"tax-category\"]),\n\t\"attribute-group\": new AttributeGroupService(\n\t\trouter,\n\t\trepos[\"attribute-group\"],\n\t),\n\ttype: new TypeService(router, repos.type),\n\tzone: new ZoneService(router, repos.zone),\n});\n","import type { Update } from \"@commercetools/platform-sdk\";\nimport type { Request, Response, Router } from \"express\";\nimport { updateRequestSchema } from \"#src/schemas/update-request.ts\";\nimport { validateData } from \"#src/validate.ts\";\nimport { getRepositoryContext } from \"../repositories/helpers.ts\";\nimport type { ProjectRepository } from \"../repositories/project.ts\";\n\nexport class ProjectService {\n\tpublic repository: ProjectRepository;\n\n\tconstructor(parent: Router, repository: ProjectRepository) {\n\t\tthis.repository = repository;\n\t\tthis.registerRoutes(parent);\n\t}\n\n\tregisterRoutes(parent: Router) {\n\t\tparent.get(\"\", this.get.bind(this));\n\t\tparent.post(\"\", this.post.bind(this));\n\t}\n\n\tget(request: Request, response: Response) {\n\t\tconst project = this.repository.get(getRepositoryContext(request));\n\t\tresponse.status(200).send(project);\n\t}\n\n\tpost(request: Request, response: Response) {\n\t\tconst updateRequest = validateData<Update>(\n\t\t\trequest.body,\n\t\t\tupdateRequestSchema,\n\t\t);\n\t\tconst project = this.repository.get(getRepositoryContext(request));\n\n\t\tif (!project) {\n\t\t\tresponse.status(404).send({ statusCode: 404 });\n\t\t\treturn;\n\t\t}\n\n\t\tconst updatedResource = this.repository.processUpdateActions(\n\t\t\tgetRepositoryContext(request),\n\t\t\tproject,\n\t\t\tupdateRequest.version,\n\t\t\tupdateRequest.actions,\n\t\t);\n\n\t\tresponse.status(200).send(updatedResource);\n\t}\n}\n","import type {\n\tBaseResource,\n\tProject,\n\tQueryParam,\n\tResourceIdentifier,\n} from \"@commercetools/platform-sdk\";\nimport type {\n\tPagedQueryResponseMap,\n\tResourceMap,\n\tResourceType,\n} from \"../types.ts\";\n\nexport type GetParams = {\n\texpand?: string[];\n};\n\nexport type QueryParams = {\n\texpand?: string | string[];\n\tsort?: string | string[];\n\tlimit?: number;\n\toffset?: number;\n\twithTotal?: boolean;\n\twhere?: string | string[];\n\t[key: string]: QueryParam;\n};\n\nexport abstract class AbstractStorage {\n\tabstract clear(): void;\n\n\tabstract all<RT extends ResourceType>(\n\t\tprojectKey: string,\n\t\ttypeId: RT,\n\t): Array<ResourceMap[RT]>;\n\n\tabstract add<RT extends ResourceType>(\n\t\tprojectKey: string,\n\t\ttypeId: RT,\n\t\tobj: ResourceMap[RT],\n\t): ResourceMap[RT];\n\n\tabstract get<RT extends ResourceType>(\n\t\tprojectKey: string,\n\t\ttypeId: RT,\n\t\tid: string,\n\t\tparams?: GetParams,\n\t): ResourceMap[RT] | null;\n\n\tabstract getByKey<RT extends ResourceType>(\n\t\tprojectKey: string,\n\t\ttypeId: RT,\n\t\tkey: string,\n\t\tparams: GetParams,\n\t): ResourceMap[RT] | null;\n\n\tabstract addProject(projectKey: string): Project;\n\n\tabstract getProject(projectKey: string): Project;\n\n\tabstract saveProject(project: Project): Project;\n\n\tabstract delete<RT extends ResourceType>(\n\t\tprojectKey: string,\n\t\ttypeId: RT,\n\t\tid: string,\n\t\tparams: GetParams,\n\t): ResourceMap[RT] | null;\n\n\tabstract query<RT extends ResourceType>(\n\t\tprojectKey: string,\n\t\ttypeId: RT,\n\t\tparams: QueryParams,\n\t): PagedQueryResponseMap[RT];\n\n\tabstract getByResourceIdentifier<RT extends ResourceType>(\n\t\tprojectKey: string,\n\t\tidentifier: ResourceIdentifier,\n\t): ResourceMap[RT];\n\n\tabstract expand<T>(\n\t\tprojectKey: string,\n\t\tobj: T,\n\t\tclause: undefined | string | string[],\n\t): T;\n}\n\nexport type ProjectStorage = {\n\t[index in ResourceType]: Map<string, BaseResource>;\n};\n","import assert from \"node:assert\";\nimport type {\n\tAssociateRole,\n\tAttributeGroup,\n\tBusinessUnit,\n\tCart,\n\tCartDiscount,\n\tCategory,\n\tChannel,\n\tCustomer,\n\tCustomerGroup,\n\tCustomObject,\n\tDiscountCode,\n\tDiscountGroup,\n\tExtension,\n\tInvalidInputError,\n\tInvalidJsonInputError,\n\tInventoryEntry,\n\tOrder,\n\tPagedQueryResponse,\n\tPayment,\n\tProduct,\n\tProductDiscount,\n\tProductProjection,\n\tProductTailoring,\n\tProductType,\n\tProject,\n\tQuote,\n\tQuoteRequest,\n\tRecurrencePolicy,\n\tRecurringOrder,\n\tReference,\n\tReferencedResourceNotFoundError,\n\tResourceIdentifier,\n\tShippingMethod,\n\tShoppingList,\n\tShoppingListLineItem,\n\tStagedQuote,\n\tState,\n\tStore,\n\tSubscription,\n\tTaxCategory,\n\tType,\n\tZone,\n} from \"@commercetools/platform-sdk\";\nimport { CommercetoolsError } from \"#src/exceptions.ts\";\nimport { cloneObject } from \"../helpers.ts\";\nimport { parseExpandClause } from \"../lib/expandParser.ts\";\nimport { parseQueryExpression } from \"../lib/predicateParser.ts\";\nimport type {\n\tPagedQueryResponseMap,\n\tResourceMap,\n\tResourceType,\n\tWritable,\n} from \"../types.ts\";\nimport type { GetParams, ProjectStorage, QueryParams } from \"./abstract.ts\";\nimport { AbstractStorage } from \"./abstract.ts\";\n\nexport class InMemoryStorage extends AbstractStorage {\n\tprotected resources: {\n\t\t[projectKey: string]: ProjectStorage;\n\t} = {};\n\n\tprotected projects: {\n\t\t[projectKey: string]: Project;\n\t} = {};\n\n\taddProject = (projectKey: string): Project => {\n\t\tif (!this.projects[projectKey]) {\n\t\t\tthis.projects[projectKey] = {\n\t\t\t\tkey: projectKey,\n\t\t\t\tname: \"\",\n\t\t\t\tcountries: [],\n\t\t\t\tcurrencies: [],\n\t\t\t\tlanguages: [],\n\t\t\t\tcreatedAt: \"2018-10-04T11:32:12.603Z\",\n\t\t\t\ttrialUntil: \"2018-12\",\n\t\t\t\tcarts: {\n\t\t\t\t\tcountryTaxRateFallbackEnabled: false,\n\t\t\t\t\tdeleteDaysAfterLastModification: 90,\n\t\t\t\t\tpriceRoundingMode: \"HalfEven\",\n\t\t\t\t\ttaxRoundingMode: \"HalfEven\",\n\t\t\t\t},\n\t\t\t\tshoppingLists: {\n\t\t\t\t\tdeleteDaysAfterLastModification: 360,\n\t\t\t\t},\n\t\t\t\tmessages: { enabled: false, deleteDaysAfterCreation: 15 },\n\t\t\t\tshippingRateInputType: undefined,\n\t\t\t\texternalOAuth: undefined,\n\t\t\t\tsearchIndexing: {\n\t\t\t\t\tproducts: {\n\t\t\t\t\t\tstatus: \"Deactivated\",\n\t\t\t\t\t},\n\t\t\t\t\tproductsSearch: {\n\t\t\t\t\t\tstatus: \"Deactivated\",\n\t\t\t\t\t},\n\t\t\t\t\torders: {\n\t\t\t\t\t\tstatus: \"Deactivated\",\n\t\t\t\t\t},\n\t\t\t\t\tcustomers: {\n\t\t\t\t\t\tstatus: \"Deactivated\",\n\t\t\t\t\t},\n\t\t\t\t\tbusinessUnits: {\n\t\t\t\t\t\tstatus: \"Deactivated\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tversion: 1,\n\t\t\t};\n\t\t}\n\t\treturn this.projects[projectKey];\n\t};\n\n\tsaveProject = (project: Project): Project => {\n\t\tthis.projects[project.key] = project;\n\t\treturn project;\n\t};\n\n\tgetProject = (projectKey: string): Project => this.addProject(projectKey);\n\n\t// Expand resolves a nested reference and injects the object in the given obj\n\tpublic expand = <T>(\n\t\tprojectKey: string,\n\t\tobj: T,\n\t\tclause: undefined | string | string[],\n\t): T => {\n\t\tif (!clause) return obj;\n\t\tconst newObj = cloneObject(obj);\n\t\tif (Array.isArray(clause)) {\n\t\t\tfor (const c of clause) {\n\t\t\t\tthis._resolveResource(projectKey, newObj, c);\n\t\t\t}\n\t\t} else {\n\t\t\tthis._resolveResource(projectKey, newObj, clause);\n\t\t}\n\t\treturn newObj;\n\t};\n\n\tprivate _resolveResource = (projectKey: string, obj: any, expand: string) => {\n\t\tconst params = parseExpandClause(expand);\n\n\t\t// 'lineItems[*].variant' on ShoppingList is an exception, these variants are not references\n\t\tif (params.index === \"*\") {\n\t\t\tconst reference = obj[params.element];\n\t\t\tif (\n\t\t\t\tparams.element === \"lineItems\" &&\n\t\t\t\tparams.rest?.startsWith(\"variant\") &&\n\t\t\t\treference.every(\n\t\t\t\t\t(item: any) =>\n\t\t\t\t\t\titem.variant === undefined && item.variantId !== undefined,\n\t\t\t\t)\n\t\t\t) {\n\t\t\t\tfor (const item of reference as ShoppingListLineItem[]) {\n\t\t\t\t\tthis._resolveShoppingListLineItemVariant(projectKey, item);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (!params.index) {\n\t\t\tconst reference = obj[params.element];\n\t\t\tif (reference === undefined) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis._resolveReference(projectKey, reference, params.rest);\n\t\t} else if (params.index === \"*\") {\n\t\t\tconst reference = obj[params.element];\n\t\t\tif (reference === undefined || !Array.isArray(reference)) return;\n\t\t\tfor (const itemRef of reference as Writable<Reference>[]) {\n\t\t\t\tthis._resolveReference(projectKey, itemRef, params.rest);\n\t\t\t}\n\t\t} else {\n\t\t\tconst reference = obj[params.element][params.index];\n\t\t\tif (reference === undefined) return;\n\t\t\tthis._resolveReference(projectKey, reference, params.rest);\n\t\t}\n\t};\n\n\tprivate forProjectKey(projectKey: string): ProjectStorage {\n\t\tthis.addProject(projectKey);\n\n\t\tlet projectStorage = this.resources[projectKey];\n\t\tif (!projectStorage) {\n\t\t\tprojectStorage = this.resources[projectKey] = {\n\t\t\t\t\"associate-role\": new Map<string, AssociateRole>(),\n\t\t\t\t\"attribute-group\": new Map<string, AttributeGroup>(),\n\t\t\t\t\"business-unit\": new Map<string, BusinessUnit>(),\n\t\t\t\tcart: new Map<string, Cart>(),\n\t\t\t\t\"cart-discount\": new Map<string, CartDiscount>(),\n\t\t\t\tcategory: new Map<string, Category>(),\n\t\t\t\tchannel: new Map<string, Channel>(),\n\t\t\t\tcustomer: new Map<string, Customer>(),\n\t\t\t\t\"customer-group\": new Map<string, CustomerGroup>(),\n\t\t\t\t\"discount-code\": new Map<string, DiscountCode>(),\n\t\t\t\t\"discount-group\": new Map<string, DiscountGroup>(),\n\t\t\t\textension: new Map<string, Extension>(),\n\t\t\t\t\"inventory-entry\": new Map<string, InventoryEntry>(),\n\t\t\t\t\"key-value-document\": new Map<string, CustomObject>(),\n\t\t\t\torder: new Map<string, Order>(),\n\t\t\t\t\"order-edit\": new Map<string, any>(),\n\t\t\t\tpayment: new Map<string, Payment>(),\n\t\t\t\tproduct: new Map<string, Product>(),\n\t\t\t\tquote: new Map<string, Quote>(),\n\t\t\t\t\"quote-request\": new Map<string, QuoteRequest>(),\n\t\t\t\t\"product-discount\": new Map<string, ProductDiscount>(),\n\t\t\t\t\"product-selection\": new Map<string, any>(),\n\t\t\t\t\"product-type\": new Map<string, ProductType>(),\n\t\t\t\t\"product-projection\": new Map<string, ProductProjection>(),\n\t\t\t\t\"product-tailoring\": new Map<string, ProductTailoring>(),\n\t\t\t\t\"recurrence-policy\": new Map<string, RecurrencePolicy>(),\n\t\t\t\t\"recurring-order\": new Map<string, RecurringOrder>(),\n\t\t\t\treview: new Map<string, any>(),\n\t\t\t\t\"shipping-method\": new Map<string, ShippingMethod>(),\n\t\t\t\t\"staged-quote\": new Map<string, StagedQuote>(),\n\t\t\t\tstate: new Map<string, State>(),\n\t\t\t\tstore: new Map<string, Store>(),\n\t\t\t\t\"shopping-list\": new Map<string, ShoppingList>(),\n\t\t\t\t\"standalone-price\": new Map<string, any>(),\n\t\t\t\tsubscription: new Map<string, Subscription>(),\n\t\t\t\t\"tax-category\": new Map<string, TaxCategory>(),\n\t\t\t\ttype: new Map<string, Type>(),\n\t\t\t\tzone: new Map<string, Zone>(),\n\t\t\t};\n\t\t}\n\t\treturn projectStorage;\n\t}\n\n\tclear() {\n\t\tfor (const [, projectStorage] of Object.entries(this.resources)) {\n\t\t\tfor (const [, value] of Object.entries(projectStorage)) {\n\t\t\t\tvalue?.clear();\n\t\t\t}\n\t\t}\n\t}\n\n\tall<RT extends ResourceType>(\n\t\tprojectKey: string,\n\t\ttypeId: RT,\n\t): ResourceMap[RT][] {\n\t\tconst store = this.forProjectKey(projectKey)[typeId];\n\t\tif (store) {\n\t\t\treturn Array.from(store.values()).map(cloneObject) as ResourceMap[RT][];\n\t\t}\n\t\treturn [];\n\t}\n\n\tadd<RT extends ResourceType>(\n\t\tprojectKey: string,\n\t\ttypeId: RT,\n\t\tobj: ResourceMap[RT],\n\t\tparams: GetParams = {},\n\t): ResourceMap[RT] {\n\t\tconst store = this.forProjectKey(projectKey);\n\t\tstore[typeId]?.set(obj.id, obj);\n\n\t\tconst resource = this.get(projectKey, typeId, obj.id, params);\n\t\tassert(\n\t\t\tresource,\n\t\t\t`resource of type ${typeId} with id ${obj.id} not created`,\n\t\t);\n\t\treturn cloneObject(resource);\n\t}\n\n\tget<RT extends ResourceType>(\n\t\tprojectKey: string,\n\t\ttypeId: RT,\n\t\tid: string,\n\t\tparams: GetParams = {},\n\t): ResourceMap[RT] | null {\n\t\tconst resource = this.forProjectKey(projectKey)[typeId]?.get(id);\n\t\tif (resource) {\n\t\t\tconst clone = cloneObject(resource);\n\t\t\treturn this.expand(projectKey, clone, params.expand) as ResourceMap[RT];\n\t\t}\n\t\treturn null;\n\t}\n\n\tgetByKey<RT extends ResourceType>(\n\t\tprojectKey: string,\n\t\ttypeId: RT,\n\t\tkey: string,\n\t\tparams: GetParams = {},\n\t): ResourceMap[RT] | null {\n\t\tconst store = this.forProjectKey(projectKey);\n\t\tconst resourceStore = store[typeId];\n\t\tif (!store) {\n\t\t\tthrow new Error(\"No type\");\n\t\t}\n\n\t\tconst resources: any[] = Array.from(resourceStore.values());\n\t\tconst resource = resources.find((e) => e.key === key);\n\t\tif (resource) {\n\t\t\tconst clone = cloneObject(resource);\n\t\t\treturn this.expand(projectKey, clone, params.expand) as ResourceMap[RT];\n\t\t}\n\t\treturn null;\n\t}\n\n\tdelete<RT extends ResourceType>(\n\t\tprojectKey: string,\n\t\ttypeId: RT,\n\t\tid: string,\n\t\tparams: GetParams = {},\n\t): ResourceMap[RT] | null {\n\t\tconst resource = this.get(projectKey, typeId, id);\n\n\t\tif (resource) {\n\t\t\tthis.forProjectKey(projectKey)[typeId]?.delete(id);\n\t\t\treturn this.expand(projectKey, resource, params.expand);\n\t\t}\n\t\treturn resource;\n\t}\n\n\tquery<RT extends ResourceType>(\n\t\tprojectKey: string,\n\t\ttypeId: RT,\n\t\tparams: QueryParams,\n\t): PagedQueryResponseMap[RT] {\n\t\tconst store = this.forProjectKey(projectKey)[typeId];\n\t\tif (!store) {\n\t\t\tthrow new Error(\"No type\");\n\t\t}\n\n\t\tlet resources = this.all<RT>(projectKey, typeId);\n\n\t\t// Apply predicates\n\t\tif (params.where) {\n\t\t\t// Get all key-value pairs starting with 'var.' to pass as variables, removing\n\t\t\t// the 'var.' prefix.\n\t\t\tconst vars = Object.fromEntries(\n\t\t\t\tObject.entries(params)\n\t\t\t\t\t.filter(([key]) => key.startsWith(\"var.\"))\n\t\t\t\t\t.map(([key, value]) => [key.slice(4), value]),\n\t\t\t);\n\n\t\t\ttry {\n\t\t\t\tconst filterFunc = parseQueryExpression(params.where);\n\t\t\t\tresources = resources.filter((resource) => filterFunc(resource, vars));\n\t\t\t} catch (err) {\n\t\t\t\tthrow new CommercetoolsError<InvalidInputError>(\n\t\t\t\t\t{\n\t\t\t\t\t\tcode: \"InvalidInput\",\n\t\t\t\t\t\tmessage: (err as any).message,\n\t\t\t\t\t},\n\t\t\t\t\t400,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\t// Get the total before slicing the array\n\t\tconst totalResources = resources.length;\n\n\t\t// Apply offset, limit\n\t\tconst offset = params.offset || 0;\n\t\tconst limit = params.limit || 20;\n\t\tresources = resources.slice(offset, offset + limit);\n\n\t\t// Expand the resources\n\t\tif (params.expand !== undefined) {\n\t\t\tresources = resources.map((resource) =>\n\t\t\t\tthis.expand(projectKey, resource, params.expand),\n\t\t\t);\n\t\t}\n\n\t\treturn {\n\t\t\tcount: totalResources,\n\t\t\ttotal: resources.length,\n\t\t\toffset: offset,\n\t\t\tlimit: limit,\n\t\t\tresults: resources.map(cloneObject),\n\t\t} as PagedQueryResponseMap[RT];\n\t}\n\n\tsearch(\n\t\tprojectKey: string,\n\t\ttypeId: ResourceType,\n\t\tparams: QueryParams,\n\t): PagedQueryResponse {\n\t\tlet resources = this.all(projectKey, typeId);\n\n\t\t// Apply predicates\n\t\tif (params.where) {\n\t\t\ttry {\n\t\t\t\tconst filterFunc = parseQueryExpression(params.where);\n\t\t\t\tresources = resources.filter((resource) => filterFunc(resource, {}));\n\t\t\t} catch (err) {\n\t\t\t\tthrow new CommercetoolsError<InvalidInputError>(\n\t\t\t\t\t{\n\t\t\t\t\t\tcode: \"InvalidInput\",\n\t\t\t\t\t\tmessage: (err as any).message,\n\t\t\t\t\t},\n\t\t\t\t\t400,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\t// Get the total before slicing the array\n\t\tconst totalResources = resources.length;\n\n\t\t// Apply offset, limit\n\t\tconst offset = params.offset || 0;\n\t\tconst limit = params.limit || 20;\n\t\tresources = resources.slice(offset, offset + limit);\n\n\t\t// Expand the resources\n\t\tif (params.expand !== undefined) {\n\t\t\tresources = resources.map((resource) =>\n\t\t\t\tthis.expand(projectKey, resource, params.expand),\n\t\t\t);\n\t\t}\n\n\t\treturn {\n\t\t\tcount: totalResources,\n\t\t\ttotal: resources.length,\n\t\t\toffset: offset,\n\t\t\tlimit: limit,\n\t\t\tresults: resources,\n\t\t};\n\t}\n\n\tgetByResourceIdentifier<RT extends ResourceType>(\n\t\tprojectKey: string,\n\t\tidentifier: ResourceIdentifier,\n\t): ResourceMap[RT] {\n\t\tif (identifier.id) {\n\t\t\tconst resource = this.get(projectKey, identifier.typeId, identifier.id);\n\t\t\tif (resource) {\n\t\t\t\treturn resource as ResourceMap[RT];\n\t\t\t}\n\n\t\t\tthrow new CommercetoolsError<ReferencedResourceNotFoundError>({\n\t\t\t\tcode: \"ReferencedResourceNotFound\",\n\t\t\t\tmessage: `The referenced object of type '${identifier.typeId}' with id '${identifier.id}' was not found. It either doesn't exist, or it can't be accessed from this endpoint (e.g., if the endpoint filters by store or customer account).`,\n\t\t\t\ttypeId: identifier.typeId,\n\t\t\t\tid: identifier.id,\n\t\t\t});\n\t\t}\n\n\t\tif (identifier.key) {\n\t\t\tconst resource = this.getByKey(\n\t\t\t\tprojectKey,\n\t\t\t\tidentifier.typeId,\n\t\t\t\tidentifier.key,\n\t\t\t);\n\t\t\tif (resource) {\n\t\t\t\treturn resource as ResourceMap[RT];\n\t\t\t}\n\n\t\t\tthrow new CommercetoolsError<ReferencedResourceNotFoundError>({\n\t\t\t\tcode: \"ReferencedResourceNotFound\",\n\t\t\t\tmessage: `The referenced object of type '${identifier.typeId}' with key '${identifier.key}' was not found. It either doesn't exist, or it can't be accessed from this endpoint (e.g., if the endpoint filters by store or customer account).`,\n\t\t\t\ttypeId: identifier.typeId,\n\t\t\t\tkey: identifier.key,\n\t\t\t});\n\t\t}\n\t\tthrow new CommercetoolsError<InvalidJsonInputError>({\n\t\t\tcode: \"InvalidJsonInput\",\n\t\t\tmessage: \"Request body does not contain valid JSON.\",\n\t\t\tdetailedErrorMessage: \"ResourceIdentifier requires an 'id' xor a 'key'\",\n\t\t});\n\t}\n\n\tprivate _resolveReference(\n\t\tprojectKey: string,\n\t\treference: any,\n\t\texpand: string | undefined,\n\t) {\n\t\tif (reference === undefined) return;\n\n\t\tif (\n\t\t\treference.typeId !== undefined &&\n\t\t\t(reference.id !== undefined || reference.key !== undefined)\n\t\t) {\n\t\t\t// First check if the object is already resolved. This is the case when\n\t\t\t// the complete resource is pushed via the .add() method.\n\t\t\tif (!reference.obj) {\n\t\t\t\treference.obj = this.getByResourceIdentifier(projectKey, {\n\t\t\t\t\ttypeId: reference.typeId,\n\t\t\t\t\tid: reference.id,\n\t\t\t\t\tkey: reference.key,\n\t\t\t\t} as ResourceIdentifier);\n\t\t\t}\n\t\t\tif (expand) {\n\t\t\t\tthis._resolveResource(projectKey, reference.obj, expand);\n\t\t\t}\n\t\t} else {\n\t\t\tif (expand) {\n\t\t\t\tthis._resolveResource(projectKey, reference, expand);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate _resolveShoppingListLineItemVariant(\n\t\tprojectKey: string,\n\t\tlineItem: ShoppingListLineItem,\n\t) {\n\t\tconst product = this.getByResourceIdentifier(projectKey, {\n\t\t\ttypeId: \"product\",\n\t\t\tid: lineItem.productId,\n\t\t}) as Product | undefined;\n\n\t\tif (!product) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst variant = [\n\t\t\tproduct.masterData.current.masterVariant,\n\t\t\t...product.masterData.current.variants,\n\t\t].find((e) => e.id === lineItem.variantId);\n\t\t// @ts-expect-error\n\t\tlineItem.variant = variant;\n\t}\n}\n","import type { NextFunction, Request, Response } from \"express\";\nimport express from \"express\";\nimport inject from \"light-my-request\";\nimport morgan from \"morgan\";\nimport { HttpResponse, http } from \"msw\";\nimport type { SetupServer, SetupServerApi } from \"msw/node\";\nimport { setupServer } from \"msw/node\";\nimport type { Config } from \"./config.ts\";\nimport { DEFAULT_API_HOSTNAME, DEFAULT_AUTH_HOSTNAME } from \"./constants.ts\";\nimport { CommercetoolsError } from \"./exceptions.ts\";\nimport { mapHeaderType } from \"./helpers.ts\";\nimport { copyHeaders } from \"./lib/proxy.ts\";\nimport { OAuth2Server } from \"./oauth/server.ts\";\nimport { ProjectAPI } from \"./projectAPI.ts\";\nimport type { RepositoryMap } from \"./repositories/index.ts\";\nimport { createRepositories } from \"./repositories/index.ts\";\nimport type { ProjectRepository } from \"./repositories/project.ts\";\nimport { createServices } from \"./services/index.ts\";\nimport { ProjectService } from \"./services/project.ts\";\nimport type { AbstractStorage } from \"./storage/index.ts\";\nimport { InMemoryStorage } from \"./storage/index.ts\";\n\nexport type CommercetoolsMockOptions = {\n\tvalidateCredentials: boolean;\n\tenableAuthentication: boolean;\n\tdefaultProjectKey: string | undefined;\n\tapiHost: RegExp | string;\n\tauthHost: RegExp | string;\n\tsilent: boolean;\n\tstrict: boolean;\n};\n\ntype AppOptions = { silent?: boolean };\n\nconst DEFAULT_OPTIONS: CommercetoolsMockOptions = {\n\tenableAuthentication: false,\n\tvalidateCredentials: false,\n\tdefaultProjectKey: undefined,\n\tapiHost: DEFAULT_API_HOSTNAME,\n\tauthHost: DEFAULT_AUTH_HOSTNAME,\n\tsilent: true,\n\tstrict: false,\n};\n\nconst _globalListeners: SetupServer[] = [];\n\nexport class CommercetoolsMock {\n\tpublic app: express.Express;\n\n\tpublic options: CommercetoolsMockOptions;\n\n\tprivate _storage: AbstractStorage;\n\n\tprivate _oauth2: OAuth2Server;\n\n\tprivate _mswServer: SetupServer | undefined = undefined;\n\n\tprivate _repositories: RepositoryMap | null;\n\n\t// biome-ignore lint: lint/correctness/noUnusedPrivateClassMembers\n\tprivate _projectService: ProjectService | undefined;\n\n\tconstructor(options: Partial<CommercetoolsMockOptions> = {}) {\n\t\tthis.options = { ...DEFAULT_OPTIONS, ...options };\n\t\tthis._repositories = null;\n\t\tthis._projectService = undefined;\n\n\t\tthis._storage = new InMemoryStorage();\n\t\tthis._oauth2 = new OAuth2Server({\n\t\t\tenabled: this.options.enableAuthentication,\n\t\t\tvalidate: this.options.validateCredentials,\n\t\t});\n\n\t\tthis.app = this.createApp({ silent: this.options.silent });\n\t}\n\n\tstart() {\n\t\tprocess.emitWarning(\n\t\t\t\"The start() method is deprecated, use .registerHandlers() to bind to an msw server instead\",\n\t\t\t\"DeprecationWarning\",\n\t\t);\n\n\t\t// Order is important here when the hostnames match\n\t\tthis.clear();\n\t\tthis.startServer();\n\t}\n\n\tstop() {\n\t\tprocess.emitWarning(\n\t\t\t\"The stop() method is deprecated, use .registerHandlers() to bind to an msw server instead\",\n\t\t\t\"DeprecationWarning\",\n\t\t);\n\t\tthis._mswServer?.close();\n\t\tthis._mswServer = undefined;\n\t}\n\n\tclear() {\n\t\tthis._storage.clear();\n\t}\n\n\tproject(projectKey?: string) {\n\t\tif (!projectKey && !this.options.defaultProjectKey) {\n\t\t\tthrow new Error(\"No projectKey passed and no default set\");\n\t\t}\n\n\t\tif (this._repositories === null) {\n\t\t\tthrow new Error(\"repositories not initialized yet\");\n\t\t}\n\n\t\tconst config: Config = {\n\t\t\tstrict: this.options.strict,\n\t\t\tstorage: this._storage,\n\t\t};\n\n\t\treturn new ProjectAPI(\n\t\t\tprojectKey || this.options.defaultProjectKey!,\n\t\t\tthis._repositories,\n\t\t\tconfig,\n\t\t);\n\t}\n\n\tauthStore() {\n\t\treturn this._oauth2.store;\n\t}\n\n\trunServer(port = 3000, options?: AppOptions) {\n\t\tconst server = this.app.listen(port, () => {});\n\t\tserver.keepAliveTimeout = 60 * 1000;\n\t}\n\n\tprivate createApp(options?: AppOptions): express.Express {\n\t\tconst config: Config = {\n\t\t\tstrict: this.options.strict,\n\t\t\tstorage: this._storage,\n\t\t};\n\t\tthis._repositories = createRepositories(config);\n\t\tthis._oauth2.setCustomerRepository(this._repositories.customer);\n\n\t\tconst app = express();\n\t\t// Set limit to 16mb, this is the maximum size allowed by the commercetools API: https://docs.commercetools.com/api/limits\n\t\tapp.use(express.json({ limit: \"16mb\" }));\n\n\t\tconst projectRouter = express.Router({ mergeParams: true });\n\n\t\tif (!options?.silent) {\n\t\t\tapp.use(morgan(\"tiny\"));\n\t\t}\n\t\tapp.use(\"/oauth\", this._oauth2.createRouter());\n\n\t\t// Only enable auth middleware if we have enabled this\n\t\tif (this.options.enableAuthentication) {\n\t\t\tapp.use(\"/:projectKey\", this._oauth2.createMiddleware(), projectRouter);\n\t\t\tapp.use(\n\t\t\t\t\"/:projectKey/in-store/key=:storeKey\",\n\t\t\t\tthis._oauth2.createMiddleware(),\n\t\t\t\tprojectRouter,\n\t\t\t);\n\t\t} else {\n\t\t\tapp.use(\"/:projectKey\", projectRouter);\n\t\t\tapp.use(\"/:projectKey/in-store/key=:storeKey\", projectRouter);\n\t\t}\n\n\t\t// Register the rest api services in the router\n\t\tcreateServices(projectRouter, this._repositories);\n\t\tthis._projectService = new ProjectService(\n\t\t\tprojectRouter,\n\t\t\tthis._repositories.project as ProjectRepository,\n\t\t);\n\n\t\tapp.use((err: Error, req: Request, resp: Response, next: NextFunction) => {\n\t\t\tif (err instanceof CommercetoolsError) {\n\t\t\t\tif (err.errors?.length > 0) {\n\t\t\t\t\tresp.status(err.statusCode).send({\n\t\t\t\t\t\tstatusCode: err.statusCode,\n\t\t\t\t\t\tmessage: err.message,\n\t\t\t\t\t\terrors: err.errors,\n\t\t\t\t\t});\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tresp.status(err.statusCode).send({\n\t\t\t\t\tstatusCode: err.statusCode,\n\t\t\t\t\tmessage: err.message,\n\t\t\t\t\terrors: [err.info],\n\t\t\t\t});\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tresp.status(500).send({\n\t\t\t\terror: err.message,\n\t\t\t});\n\t\t\treturn;\n\t\t});\n\n\t\treturn app;\n\t}\n\n\t// registerHandlers is an alternative way to work with commercetools-mock, it\n\t// allows you to manage msw server yourself and register the handlers needed\n\t// for commercetools-mock to work.\n\tpublic registerHandlers(server: SetupServerApi) {\n\t\tconst handlers = this.getHandlers();\n\t\tserver.use(...handlers);\n\t}\n\n\tpublic getHandlers() {\n\t\tconst app = this.app;\n\t\treturn [\n\t\t\thttp.post(`${this.options.authHost}/oauth/*`, async ({ request }) => {\n\t\t\t\tconst body = await request.text();\n\t\t\t\tconst url = new URL(request.url);\n\t\t\t\tconst headers = copyHeaders(request.headers);\n\n\t\t\t\tconst res = await inject(app)\n\t\t\t\t\t.post(`${url.pathname}?${url.searchParams.toString()}`)\n\t\t\t\t\t.body(body)\n\t\t\t\t\t.headers(headers)\n\t\t\t\t\t.end();\n\t\t\t\treturn new HttpResponse(res.body, {\n\t\t\t\t\tstatus: res.statusCode,\n\t\t\t\t\theaders: mapHeaderType(res.headers),\n\t\t\t\t});\n\t\t\t}),\n\t\t\thttp.head(`${this.options.apiHost}/*`, async ({ request }) => {\n\t\t\t\tconst body = await request.text();\n\t\t\t\tconst url = new URL(request.url);\n\t\t\t\tconst headers = copyHeaders(request.headers);\n\n\t\t\t\tconst res = await inject(app)\n\t\t\t\t\t.get(`${url.pathname}?${url.searchParams.toString()}`)\n\t\t\t\t\t.body(body)\n\t\t\t\t\t.headers(headers)\n\t\t\t\t\t.end();\n\n\t\t\t\tif (res.statusCode === 200) {\n\t\t\t\t\tconst parsedBody = JSON.parse(res.body);\n\t\t\t\t\t// Check if we have a count property (e.g. for query-lookups)\n\t\t\t\t\t// or if we have a result object (e.g. for single lookups)\n\t\t\t\t\tconst resultCount =\n\t\t\t\t\t\t\"count\" in parsedBody\n\t\t\t\t\t\t\t? parsedBody.count\n\t\t\t\t\t\t\t: Object.keys(parsedBody).length;\n\n\t\t\t\t\treturn new HttpResponse(null, {\n\t\t\t\t\t\tstatus: resultCount > 0 ? 200 : 404,\n\t\t\t\t\t\theaders: mapHeaderType(res.headers),\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\treturn new HttpResponse(null, {\n\t\t\t\t\tstatus: res.statusCode,\n\t\t\t\t\theaders: mapHeaderType(res.headers),\n\t\t\t\t});\n\t\t\t}),\n\t\t\thttp.get(`${this.options.apiHost}/*`, async ({ request }) => {\n\t\t\t\tconst body = await request.text();\n\t\t\t\tconst url = new URL(request.url);\n\t\t\t\tconst headers = copyHeaders(request.headers);\n\n\t\t\t\tconst res = await inject(app)\n\t\t\t\t\t.get(`${url.pathname}?${url.searchParams.toString()}`)\n\t\t\t\t\t.body(body)\n\t\t\t\t\t.headers(headers)\n\t\t\t\t\t.end();\n\t\t\t\treturn new HttpResponse(res.body, {\n\t\t\t\t\tstatus: res.statusCode,\n\t\t\t\t\theaders: mapHeaderType(res.headers),\n\t\t\t\t});\n\t\t\t}),\n\t\t\thttp.post(`${this.options.apiHost}/*`, async ({ request }) => {\n\t\t\t\tconst body = await request.text();\n\t\t\t\tconst url = new URL(request.url);\n\t\t\t\tconst headers = copyHeaders(request.headers);\n\n\t\t\t\tconst res = await inject(app)\n\t\t\t\t\t.post(`${url.pathname}?${url.searchParams.toString()}`)\n\t\t\t\t\t.body(body)\n\t\t\t\t\t.headers(headers)\n\t\t\t\t\t.end();\n\t\t\t\treturn new HttpResponse(res.body, {\n\t\t\t\t\tstatus: res.statusCode,\n\t\t\t\t\theaders: mapHeaderType(res.headers),\n\t\t\t\t});\n\t\t\t}),\n\t\t\thttp.delete(`${this.options.apiHost}/*`, async ({ request }) => {\n\t\t\t\tconst body = await request.text();\n\t\t\t\tconst url = new URL(request.url);\n\t\t\t\tconst headers = copyHeaders(request.headers);\n\n\t\t\t\tconst res = await inject(app)\n\t\t\t\t\t.delete(`${url.pathname}?${url.searchParams.toString()}`)\n\t\t\t\t\t.body(body)\n\t\t\t\t\t.headers(headers)\n\t\t\t\t\t.end();\n\t\t\t\treturn new HttpResponse(res.body, {\n\t\t\t\t\tstatus: res.statusCode,\n\t\t\t\t\theaders: mapHeaderType(res.headers),\n\t\t\t\t});\n\t\t\t}),\n\t\t];\n\t}\n\n\tpublic mswServer() {\n\t\treturn this._mswServer;\n\t}\n\n\tprivate startServer() {\n\t\t// Check if there are any other servers running\n\t\tif (_globalListeners.length > 0) {\n\t\t\tif (this._mswServer !== undefined) {\n\t\t\t\tthrow new Error(\"Server already started\");\n\t\t\t}\n\t\t\tprocess.emitWarning(\"Server wasn't stopped properly, clearing\");\n\t\t\tfor (const listener of _globalListeners) {\n\t\t\t\tlistener.close();\n\t\t\t}\n\t\t\t_globalListeners.length = 0;\n\t\t}\n\n\t\tconst server = setupServer();\n\t\tthis.registerHandlers(server);\n\t\tserver.listen({\n\t\t\t// We need to allow requests done by supertest\n\t\t\tonUnhandledRequest: (request, print) => {\n\t\t\t\tconst url = new URL(request.url);\n\t\t\t\tif (url.hostname === \"127.0.0.1\") {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tprint.error();\n\t\t\t},\n\t\t});\n\t\t_globalListeners.push(server);\n\t\tthis._mswServer = server;\n\t}\n}\n"],"mappings":"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"}
|