feat(medusa, core-flows, types): Allow to update the rules from a shipping options (#7175)
**What** Add support for the following operations - update rules from the update shipping options end point - update rules from the batch update end point Also added some improvements, that can be revisited later - Add a rule value normalizer, jsonb will transform the input value to a [primitive](https://www.postgresql.org/docs/current/datatype-json.html#JSON-TYPE-MAPPING-TABLE) when possible meaning that passing `"true"` will result in storing `true` and not the string. The normalizer takes care of that
This commit is contained in:
1 parent
3affcc2525
commit
e26cda4b6a
11 files changed
+470
-41
No files matched your search
@@ -14,17 +14,17 @@ import {
|
||||
UpdateServiceZoneDTO,
|
||||
} from "@medusajs/types"
|
||||
import {
|
||||
arrayDifference,
|
||||
EmitEvents,
|
||||
FulfillmentUtils,
|
||||
getSetDifference,
|
||||
InjectManager,
|
||||
InjectTransactionManager,
|
||||
isString,
|
||||
MedusaContext,
|
||||
MedusaError,
|
||||
Modules,
|
||||
ModulesSdkUtils,
|
||||
arrayDifference,
|
||||
getSetDifference,
|
||||
isString,
|
||||
promiseAll,
|
||||
} from "@medusajs/utils"
|
||||
import {
|
||||
@@ -38,9 +38,9 @@ import {
|
||||
ShippingOptionType,
|
||||
ShippingProfile,
|
||||
} from "@models"
|
||||
import { isContextValid, validateRules } from "@utils"
|
||||
import { entityNameToLinkableKeysMap, joinerConfig } from "../joiner-config"
|
||||
import { UpdateShippingOptionsInput } from "../types/service"
|
||||
import {isContextValid, validateAndNormalizeRules} from "@utils"
|
||||
import {entityNameToLinkableKeysMap, joinerConfig} from "../joiner-config"
|
||||
import {UpdateShippingOptionsInput} from "../types/service"
|
||||
import FulfillmentProviderService from "./fulfillment-provider"
|
||||
|
||||
const generateMethodForModels = [
|
||||
@@ -343,7 +343,7 @@ export default class FulfillmentModuleService<
|
||||
| FulfillmentTypes.CreateServiceZoneDTO,
|
||||
@MedusaContext() sharedContext: Context = {}
|
||||
): Promise<TServiceZoneEntity | TServiceZoneEntity[]> {
|
||||
let data_ = Array.isArray(data) ? data : [data]
|
||||
const data_ = Array.isArray(data) ? data : [data]
|
||||
|
||||
if (!data_.length) {
|
||||
return []
|
||||
@@ -402,7 +402,7 @@ export default class FulfillmentModuleService<
|
||||
| FulfillmentTypes.CreateShippingOptionDTO,
|
||||
@MedusaContext() sharedContext: Context = {}
|
||||
): Promise<TShippingOptionEntity | TShippingOptionEntity[]> {
|
||||
let data_ = Array.isArray(data) ? data : [data]
|
||||
const data_ = Array.isArray(data) ? data : [data]
|
||||
|
||||
if (!data_.length) {
|
||||
return []
|
||||
@@ -410,7 +410,7 @@ export default class FulfillmentModuleService<
|
||||
|
||||
const rules = data_.flatMap((d) => d.rules).filter(Boolean)
|
||||
if (rules.length) {
|
||||
validateRules(rules as Record<string, unknown>[])
|
||||
validateAndNormalizeRules(rules as Record<string, unknown>[])
|
||||
}
|
||||
|
||||
const createdShippingOptions = await this.shippingOptionService_.create(
|
||||
@@ -555,7 +555,7 @@ export default class FulfillmentModuleService<
|
||||
return []
|
||||
}
|
||||
|
||||
validateRules(data_ as unknown as Record<string, unknown>[])
|
||||
validateAndNormalizeRules(data_ as unknown as Record<string, unknown>[])
|
||||
|
||||
const createdShippingOptionRules =
|
||||
await this.shippingOptionRuleService_.create(data_, sharedContext)
|
||||
@@ -1175,7 +1175,7 @@ export default class FulfillmentModuleService<
|
||||
})
|
||||
.filter(Boolean)
|
||||
|
||||
validateRules(newRules as Record<string, unknown>[])
|
||||
validateAndNormalizeRules(newRules as Record<string, unknown>[])
|
||||
|
||||
shippingOption.rules = shippingOption.rules.map((rule) => {
|
||||
if (!("id" in rule)) {
|
||||
@@ -1382,7 +1382,7 @@ export default class FulfillmentModuleService<
|
||||
return []
|
||||
}
|
||||
|
||||
validateRules(data_ as unknown as Record<string, unknown>[])
|
||||
validateAndNormalizeRules(data_ as unknown as Record<string, unknown>[])
|
||||
|
||||
const updatedShippingOptionRules =
|
||||
await this.shippingOptionRuleService_.update(data_, sharedContext)
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import {
|
||||
isObject,
|
||||
isString,
|
||||
MedusaError,
|
||||
pickValueFromObject,
|
||||
@@ -97,21 +98,21 @@ export function validateRule(rule: Record<string, unknown>): boolean {
|
||||
if (!rule.attribute || !rule.operator || !rule.value) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
"Rule must have an attribute, an operator and contextValue value"
|
||||
"Rule must have an attribute, an operator and a value"
|
||||
)
|
||||
}
|
||||
|
||||
if (!isString(rule.attribute)) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
"Rule attribute must be contextValue string"
|
||||
"Rule attribute must be a string"
|
||||
)
|
||||
}
|
||||
|
||||
if (!isString(rule.operator)) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
"Rule operator must be contextValue string"
|
||||
"Rule operator must be a string"
|
||||
)
|
||||
}
|
||||
|
||||
@@ -132,10 +133,10 @@ export function validateRule(rule: Record<string, unknown>): boolean {
|
||||
)
|
||||
}
|
||||
} else {
|
||||
if (!isString(rule.value)) {
|
||||
if (Array.isArray(rule.value) || isObject(rule.value)) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
`Rule value must be a string for the selected operator ${rule.operator}`
|
||||
`Rule value must be a string, bool, number value for the selected operator ${rule.operator}`
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -143,6 +144,24 @@ export function validateRule(rule: Record<string, unknown>): boolean {
|
||||
return true
|
||||
}
|
||||
|
||||
export function normalizeRulesValue<T extends Partial<Rule>>(rules: T[]): void {
|
||||
rules.forEach((rule) => {
|
||||
/**
|
||||
* If a string is provided, then we don't want jsonb to convert to the primitive value based on the RFC
|
||||
*/
|
||||
if (rule.value === "true" || rule.value === "false") {
|
||||
rule.value = rule.value === "true" ? '"true"' : '"false"'
|
||||
}
|
||||
|
||||
return rule
|
||||
})
|
||||
}
|
||||
|
||||
export function validateAndNormalizeRules<T extends Partial<Rule>>(rules: T[]) {
|
||||
rules.forEach(validateRule)
|
||||
normalizeRulesValue(rules)
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate contextValue set of rules
|
||||
* @param rules
|
||||
|
||||
Reference in new issue
Block a user