feat(medusa): Refactor undefined check into a single util (#2024)

This commit is contained in:
Adrien de Peretti
2022-08-10 17:45:48 +02:00
committed by GitHub
parent bd031ef7ad
commit c31290c911
37 changed files with 118 additions and 94 deletions
+5
View File
@@ -0,0 +1,5 @@
---
"@medusajs/medusa": patch
---
Add new `isDefined` utility
@@ -6,6 +6,7 @@ import { DateComparisonOperator } from "../../../../types/common"
import { IsType } from "../../../../utils/validators/is-type" import { IsType } from "../../../../utils/validators/is-type"
import { Request } from "express" import { Request } from "express"
import { pickBy } from "lodash" import { pickBy } from "lodash"
import { isDefined } from "../../../../utils"
/** /**
* @oas [get] /batch-jobs * @oas [get] /batch-jobs
@@ -238,9 +239,8 @@ export default async (req: Request, res) => {
const created_by = req.user?.id || req.user?.userId const created_by = req.user?.id || req.user?.userId
const [jobs, count] = await batchService.listAndCount( const [jobs, count] = await batchService.listAndCount(
pickBy( pickBy({ created_by, ...(req.filterableFields ?? {}) }, (val) =>
{ created_by, ...(req.filterableFields ?? {}) }, isDefined(val)
(val) => typeof val !== "undefined"
), ),
req.listConfig req.listConfig
) )
@@ -14,6 +14,7 @@ import { Discount } from "../../../.."
import DiscountService from "../../../../services/discount" import DiscountService from "../../../../services/discount"
import { FindConfig } from "../../../../types/common" import { FindConfig } from "../../../../types/common"
import { validator } from "../../../../utils/validator" import { validator } from "../../../../utils/validator"
import { isDefined } from "../../../../utils"
/** /**
* @oas [get] /discounts * @oas [get] /discounts
@@ -84,7 +85,7 @@ export default async (req, res) => {
const filterableFields = _.omit(validated, ["limit", "offset", "expand"]) const filterableFields = _.omit(validated, ["limit", "offset", "expand"])
const [discounts, count] = await discountService.listAndCount( const [discounts, count] = await discountService.listAndCount(
pickBy(filterableFields, (val) => typeof val !== "undefined"), pickBy(filterableFields, (val) => isDefined(val)),
listConfig listConfig
) )
@@ -4,6 +4,7 @@ import { GiftCardService } from "../../../../services"
import { Type } from "class-transformer" import { Type } from "class-transformer"
import { pickBy } from "lodash" import { pickBy } from "lodash"
import { validator } from "../../../../utils/validator" import { validator } from "../../../../utils/validator"
import { isDefined } from "../../../../utils"
/** /**
* @oas [get] /gift-cards * @oas [get] /gift-cards
@@ -44,7 +45,7 @@ export default async (req, res) => {
const giftCardService: GiftCardService = req.scope.resolve("giftCardService") const giftCardService: GiftCardService = req.scope.resolve("giftCardService")
const [giftCards, count] = await giftCardService.listAndCount( const [giftCards, count] = await giftCardService.listAndCount(
pickBy(req.filterableFields, (val) => typeof val !== "undefined"), pickBy(req.filterableFields, (val) => isDefined(val)),
req.listConfig req.listConfig
) )
@@ -18,6 +18,7 @@ import { OrdersReturnItem } from "../../../../types/orders"
import { Type } from "class-transformer" import { Type } from "class-transformer"
import { validator } from "../../../../utils/validator" import { validator } from "../../../../utils/validator"
import { EntityManager } from "typeorm" import { EntityManager } from "typeorm"
import { isDefined } from "../../../../utils"
/** /**
* @oas [post] /orders/{id}/return * @oas [post] /orders/{id}/return
@@ -140,7 +141,7 @@ export default async (req, res) => {
returnObj.shipping_method = value.return_shipping returnObj.shipping_method = value.return_shipping
} }
if (typeof value.refund !== "undefined" && value.refund < 0) { if (isDefined(value.refund) && value.refund < 0) {
returnObj.refund_amount = 0 returnObj.refund_amount = 0
} else { } else {
if (value.refund && value.refund >= 0) { if (value.refund && value.refund >= 0) {
@@ -17,6 +17,7 @@ import { ProductStatus } from "../../../../models"
import { Request } from "express" import { Request } from "express"
import { Type } from "class-transformer" import { Type } from "class-transformer"
import { pickBy } from "lodash" import { pickBy } from "lodash"
import { isDefined } from "../../../../utils"
/** /**
* @oas [get] /price-lists/:id/products * @oas [get] /price-lists/:id/products
@@ -168,7 +169,7 @@ export default async (req: Request, res) => {
const [products, count] = await priceListService.listProducts( const [products, count] = await priceListService.listProducts(
id, id,
pickBy(filterableFields, (val) => typeof val !== "undefined"), pickBy(filterableFields, (val) => isDefined(val)),
req.listConfig req.listConfig
) )
@@ -17,6 +17,7 @@ import { ProductTag } from "../../../../models/product-tag"
import ProductTagService from "../../../../services/product-tag" import ProductTagService from "../../../../services/product-tag"
import { Type } from "class-transformer" import { Type } from "class-transformer"
import { validator } from "../../../../utils/validator" import { validator } from "../../../../utils/validator"
import { isDefined } from "../../../../utils"
/** /**
* @oas [get] /product-tags * @oas [get] /product-tags
@@ -124,7 +125,7 @@ export default async (req, res) => {
take: validated.limit, take: validated.limit,
} }
if (typeof validated.order !== "undefined") { if (isDefined(validated.order)) {
let orderField = validated.order let orderField = validated.order
if (validated.order.startsWith("-")) { if (validated.order.startsWith("-")) {
const [, field] = validated.order.split("-") const [, field] = validated.order.split("-")
@@ -17,6 +17,7 @@ import { ProductType } from "../../../../models/product-type"
import ProductTypeService from "../../../../services/product-type" import ProductTypeService from "../../../../services/product-type"
import { Type } from "class-transformer" import { Type } from "class-transformer"
import { validator } from "../../../../utils/validator" import { validator } from "../../../../utils/validator"
import { isDefined } from "../../../../utils"
/** /**
* @oas [get] /product-types * @oas [get] /product-types
@@ -125,7 +126,7 @@ export default async (req, res) => {
take: validated.limit, take: validated.limit,
} }
if (typeof validated.order !== "undefined") { if (isDefined(validated.order)) {
let orderField = validated.order let orderField = validated.order
if (validated.order.startsWith("-")) { if (validated.order.startsWith("-")) {
const [, field] = validated.order.split("-") const [, field] = validated.order.split("-")
@@ -10,6 +10,7 @@ import { OrderService, ReturnService, SwapService } from "../../../../services"
import { EntityManager } from "typeorm" import { EntityManager } from "typeorm"
import { Type } from "class-transformer" import { Type } from "class-transformer"
import { validator } from "../../../../utils/validator" import { validator } from "../../../../utils/validator"
import { isDefined } from "../../../../utils"
/** /**
* @oas [post] /returns/{id}/receive * @oas [post] /returns/{id}/receive
@@ -68,7 +69,7 @@ export default async (req, res) => {
await entityManager.transaction(async (manager) => { await entityManager.transaction(async (manager) => {
let refundAmount = validated.refund let refundAmount = validated.refund
if (typeof validated.refund !== "undefined" && validated.refund < 0) { if (isDefined(validated.refund) && validated.refund < 0) {
refundAmount = 0 refundAmount = 0
} }
@@ -8,6 +8,7 @@ import { TaxRate } from "../../../.."
import { TaxRateService } from "../../../../services" import { TaxRateService } from "../../../../services"
import { omit } from "lodash" import { omit } from "lodash"
import { validator } from "../../../../utils/validator" import { validator } from "../../../../utils/validator"
import { isDefined } from "../../../../utils"
/** /**
* @oas [post] /tax-rates * @oas [post] /tax-rates
@@ -98,15 +99,15 @@ export default async (req, res) => {
) )
id = created.id id = created.id
if (typeof value.products !== "undefined") { if (isDefined(value.products)) {
await txRateService.addToProduct(id, value.products) await txRateService.addToProduct(id, value.products)
} }
if (typeof value.product_types !== "undefined") { if (isDefined(value.product_types)) {
await txRateService.addToProductType(id, value.product_types) await txRateService.addToProductType(id, value.product_types)
} }
if (typeof value.shipping_options !== "undefined") { if (isDefined(value.shipping_options)) {
await txRateService.addToShippingOption(id, value.shipping_options) await txRateService.addToShippingOption(id, value.shipping_options)
} }
}) })
@@ -7,6 +7,7 @@ import { TaxRate } from "../../../.."
import { TaxRateService } from "../../../../services" import { TaxRateService } from "../../../../services"
import { omit } from "lodash" import { omit } from "lodash"
import { validator } from "../../../../utils/validator" import { validator } from "../../../../utils/validator"
import { isDefined } from "../../../../utils"
/** /**
* @oas [post] /tax-rates/:id * @oas [post] /tax-rates/:id
@@ -92,11 +93,11 @@ export default async (req, res) => {
omit(value, ["products", "product_types", "shipping_options"]) omit(value, ["products", "product_types", "shipping_options"])
) )
if (typeof value.products !== "undefined") { if (isDefined(value.products)) {
await txRateService.addToProduct(req.params.id, value.products, true) await txRateService.addToProduct(req.params.id, value.products, true)
} }
if (typeof value.product_types !== "undefined") { if (isDefined(value.product_types)) {
await txRateService.addToProductType( await txRateService.addToProductType(
req.params.id, req.params.id,
value.product_types, value.product_types,
@@ -104,7 +105,7 @@ export default async (req, res) => {
) )
} }
if (typeof value.shipping_options !== "undefined") { if (isDefined(value.shipping_options)) {
await txRateService.addToShippingOption( await txRateService.addToShippingOption(
req.params.id, req.params.id,
value.shipping_options, value.shipping_options,
@@ -2,6 +2,7 @@ import { pick } from "lodash"
import { defaultAdminTaxRatesFields, defaultAdminTaxRatesRelations } from "../" import { defaultAdminTaxRatesFields, defaultAdminTaxRatesRelations } from "../"
import { TaxRate } from "../../../../.." import { TaxRate } from "../../../../.."
import { FindConfig } from "../../../../../types/common" import { FindConfig } from "../../../../../types/common"
import { isDefined } from "../../../../../utils"
export function pickByConfig<T>( export function pickByConfig<T>(
obj: T | T[], obj: T | T[],
@@ -24,14 +25,14 @@ export function getRetrieveConfig(
expand?: string[] expand?: string[]
): FindConfig<TaxRate> { ): FindConfig<TaxRate> {
let includeFields: (keyof TaxRate)[] = [] let includeFields: (keyof TaxRate)[] = []
if (typeof fields !== "undefined") { if (isDefined(fields)) {
const fieldSet = new Set(fields) const fieldSet = new Set(fields)
fieldSet.add("id") fieldSet.add("id")
includeFields = Array.from(fieldSet) as (keyof TaxRate)[] includeFields = Array.from(fieldSet) as (keyof TaxRate)[]
} }
let expandFields: string[] = [] let expandFields: string[] = []
if (typeof expand !== "undefined") { if (isDefined(expand)) {
expandFields = expand expandFields = expand
} }
@@ -51,7 +52,7 @@ export function getListConfig(
order?: { [k: symbol]: "DESC" | "ASC" } order?: { [k: symbol]: "DESC" | "ASC" }
): FindConfig<TaxRate> { ): FindConfig<TaxRate> {
let includeFields: (keyof TaxRate)[] = [] let includeFields: (keyof TaxRate)[] = []
if (typeof fields !== "undefined") { if (isDefined(fields)) {
const fieldSet = new Set(fields) const fieldSet = new Set(fields)
// Ensure created_at is included, since we are sorting on this // Ensure created_at is included, since we are sorting on this
fieldSet.add("created_at") fieldSet.add("created_at")
@@ -60,7 +61,7 @@ export function getListConfig(
} }
let expandFields: string[] = [] let expandFields: string[] = []
if (typeof expand !== "undefined") { if (isDefined(expand)) {
expandFields = expand expandFields = expand
} }
@@ -1,7 +1,6 @@
import { CartService, LineItemService, RegionService } from "../../../../services" import { CartService, LineItemService, RegionService } from "../../../../services"
import { import {
IsArray, IsArray,
IsBoolean,
IsInt, IsInt,
IsNotEmpty, IsNotEmpty,
IsOptional, IsOptional,
@@ -19,6 +18,7 @@ import SalesChannelFeatureFlag from "../../../../loaders/feature-flags/sales-cha
import { Type } from "class-transformer" import { Type } from "class-transformer"
import { decorateLineItemsWithTotals } from "./decorate-line-items-with-totals" import { decorateLineItemsWithTotals } from "./decorate-line-items-with-totals"
import reqIp from "request-ip" import reqIp from "request-ip"
import { isDefined } from "../../../../utils";
/** /**
* @oas [post] /carts * @oas [post] /carts
@@ -91,9 +91,9 @@ export default async (req, res) => {
const entityManager: EntityManager = req.scope.resolve("manager") const entityManager: EntityManager = req.scope.resolve("manager")
const featureFlagRouter: FlagRouter = req.scope.resolve("featureFlagRouter") const featureFlagRouter: FlagRouter = req.scope.resolve("featureFlagRouter")
let regionId: string let regionId!: string
if (typeof validated.region_id !== "undefined") { if (isDefined(validated.region_id)) {
regionId = validated.region_id regionId = validated.region_id as string
} else { } else {
const regions = await regionService.list({}) const regions = await regionService.list({})
@@ -22,6 +22,7 @@ import { Product } from "../../../../models"
import { defaultStoreProductsRelations } from "." import { defaultStoreProductsRelations } from "."
import { optionalBooleanMapper } from "../../../../utils/validators/is-boolean" import { optionalBooleanMapper } from "../../../../utils/validators/is-boolean"
import { validator } from "../../../../utils/validator" import { validator } from "../../../../utils/validator"
import { isDefined } from "../../../../utils"
/** /**
* @oas [get] /products * @oas [get] /products
@@ -178,7 +179,7 @@ export default async (req, res) => {
} }
const [rawProducts, count] = await productService.listAndCount( const [rawProducts, count] = await productService.listAndCount(
pickBy(filterableFields, (val) => typeof val !== "undefined"), pickBy(filterableFields, (val) => isDefined(val)),
listConfig listConfig
) )
@@ -5,6 +5,7 @@ import { CustomerService } from "../../services"
import { FindConfig } from "../../types/common" import { FindConfig } from "../../types/common"
import { validator } from "../../utils/validator" import { validator } from "../../utils/validator"
import { Customer } from "../../models/customer" import { Customer } from "../../models/customer"
import { isDefined } from "../../utils"
const listAndCount = async ( const listAndCount = async (
scope, scope,
@@ -33,7 +34,7 @@ const listAndCount = async (
]) ])
const [customers, count] = await customerService.listAndCount( const [customers, count] = await customerService.listAndCount(
pickBy(filterableFields, (val) => typeof val !== "undefined"), pickBy(filterableFields, (val) => isDefined(val)),
listConfig listConfig
) )
@@ -5,6 +5,7 @@ import { trackFeatureFlag } from "medusa-telemetry"
import { FlagSettings } from "../../types/feature-flags" import { FlagSettings } from "../../types/feature-flags"
import { Logger } from "../../types/global" import { Logger } from "../../types/global"
import { FlagRouter } from "../../utils/flag-router" import { FlagRouter } from "../../utils/flag-router"
import { isDefined } from "../../utils"
const isTruthy = (val: string | boolean | undefined): boolean => { const isTruthy = (val: string | boolean | undefined): boolean => {
if (typeof val === "string") { if (typeof val === "string") {
@@ -36,10 +37,10 @@ export default (
flagConfig[flagSettings.key] = isTruthy(flagSettings.default_val) flagConfig[flagSettings.key] = isTruthy(flagSettings.default_val)
let from let from
if (typeof process.env[flagSettings.env_key] !== "undefined") { if (isDefined(process.env[flagSettings.env_key])) {
from = "environment" from = "environment"
flagConfig[flagSettings.key] = isTruthy(process.env[flagSettings.env_key]) flagConfig[flagSettings.key] = isTruthy(process.env[flagSettings.env_key])
} else if (typeof projectConfigFlags[flagSettings.key] !== "undefined") { } else if (isDefined(projectConfigFlags[flagSettings.key])) {
from = "project config" from = "project config"
flagConfig[flagSettings.key] = isTruthy( flagConfig[flagSettings.key] = isTruthy(
projectConfigFlags[flagSettings.key] projectConfigFlags[flagSettings.key]
+2 -1
View File
@@ -3,6 +3,7 @@ import path from "path"
import { asFunction } from "awilix" import { asFunction } from "awilix"
import formatRegistrationName from "../utils/format-registration-name" import formatRegistrationName from "../utils/format-registration-name"
import { ConfigModule, MedusaContainer } from "../types/global" import { ConfigModule, MedusaContainer } from "../types/global"
import { isDefined } from "../utils"
type Options = { type Options = {
container: MedusaContainer; container: MedusaContainer;
@@ -15,7 +16,7 @@ type Options = {
*/ */
export default ({ container, configModule, isTest }: Options): void => { export default ({ container, configModule, isTest }: Options): void => {
const useMock = const useMock =
typeof isTest !== "undefined" ? isTest : process.env.NODE_ENV === "test" isDefined(isTest) ? isTest : process.env.NODE_ENV === "test"
const corePath = useMock ? "../services/__mocks__/*.js" : "../services/*.js" const corePath = useMock ? "../services/__mocks__/*.js" : "../services/*.js"
const coreFull = path.join(__dirname, corePath) const coreFull = path.join(__dirname, corePath)
+2 -2
View File
@@ -5,6 +5,7 @@ import { asFunction, aliasTo } from "awilix"
import formatRegistrationName from "../utils/format-registration-name" import formatRegistrationName from "../utils/format-registration-name"
import { isBatchJobStrategy } from "../interfaces" import { isBatchJobStrategy } from "../interfaces"
import { MedusaContainer } from "../types/global" import { MedusaContainer } from "../types/global"
import { isDefined } from "../utils"
type LoaderOptions = { type LoaderOptions = {
container: MedusaContainer container: MedusaContainer
@@ -17,8 +18,7 @@ type LoaderOptions = {
* @returns void * @returns void
*/ */
export default ({ container, configModule, isTest }: LoaderOptions): void => { export default ({ container, configModule, isTest }: LoaderOptions): void => {
const useMock = const useMock = isDefined(isTest) ? isTest : process.env.NODE_ENV === "test"
typeof isTest !== "undefined" ? isTest : process.env.NODE_ENV === "test"
const corePath = useMock const corePath = useMock
? "../strategies/__mocks__/[!__]*.js" ? "../strategies/__mocks__/[!__]*.js"
+3 -2
View File
@@ -16,6 +16,7 @@ import { ShippingTaxRate } from "../models/shipping-tax-rate"
import { Product } from "../models/product" import { Product } from "../models/product"
import { ShippingMethod } from "../models/shipping-method" import { ShippingMethod } from "../models/shipping-method"
import { TaxRateListByConfig } from "../types/tax-rate" import { TaxRateListByConfig } from "../types/tax-rate"
import { isDefined } from "../utils"
const resolveableFields = [ const resolveableFields = [
"product_count", "product_count",
@@ -30,7 +31,7 @@ export class TaxRateRepository extends Repository<TaxRate> {
const cleanOptions = findOptions const cleanOptions = findOptions
const resolverFields: string[] = [] const resolverFields: string[] = []
if (typeof findOptions.select !== "undefined") { if (isDefined(findOptions.select)) {
let selectableCols: (keyof TaxRate)[] = [] let selectableCols: (keyof TaxRate)[] = []
for (const k of findOptions.select) { for (const k of findOptions.select) {
if (!resolveableFields.includes(k)) { if (!resolveableFields.includes(k)) {
@@ -235,7 +236,7 @@ export class TaxRateRepository extends Repository<TaxRate> {
.leftJoin(Product, "prod", "prod.type_id = pttr.product_type_id") .leftJoin(Product, "prod", "prod.type_id = pttr.product_type_id")
.where("prod.id = :productId", { productId }) .where("prod.id = :productId", { productId })
if (typeof config.region_id !== "undefined") { if (isDefined(config.region_id)) {
productRates.andWhere("txr.region_id = :regionId", { productRates.andWhere("txr.region_id = :regionId", {
regionId: config.region_id, regionId: config.region_id,
}) })
+8 -14
View File
@@ -27,7 +27,7 @@ import {
LineItemUpdate, LineItemUpdate,
} from "../types/cart" } from "../types/cart"
import { AddressPayload, FindConfig, TotalField } from "../types/common" import { AddressPayload, FindConfig, TotalField } from "../types/common"
import { buildQuery, setMetadata, validateId } from "../utils" import { buildQuery, isDefined, setMetadata, validateId } from "../utils"
import CustomShippingOptionService from "./custom-shipping-option" import CustomShippingOptionService from "./custom-shipping-option"
import CustomerService from "./customer" import CustomerService from "./customer"
import DiscountService from "./discount" import DiscountService from "./discount"
@@ -423,10 +423,7 @@ class CartService extends TransactionBaseService<CartService> {
] ]
for (const remainingField of remainingFields) { for (const remainingField of remainingFields) {
if ( if (isDefined(data[remainingField]) && remainingField !== "object") {
typeof data[remainingField] !== "undefined" &&
remainingField !== "object"
) {
const key = remainingField as string const key = remainingField as string
rawCart[key] = data[remainingField] rawCart[key] = data[remainingField]
} }
@@ -448,7 +445,7 @@ class CartService extends TransactionBaseService<CartService> {
salesChannelId?: string salesChannelId?: string
): Promise<SalesChannel | never> { ): Promise<SalesChannel | never> {
let salesChannel: SalesChannel let salesChannel: SalesChannel
if (typeof salesChannelId !== "undefined") { if (isDefined(salesChannelId)) {
salesChannel = await this.salesChannelService_ salesChannel = await this.salesChannelService_
.withTransaction(this.manager_) .withTransaction(this.manager_)
.retrieve(salesChannelId) .retrieve(salesChannelId)
@@ -858,7 +855,7 @@ class CartService extends TransactionBaseService<CartService> {
if (data.customer_id) { if (data.customer_id) {
await this.updateCustomerId_(cart, data.customer_id) await this.updateCustomerId_(cart, data.customer_id)
} else { } else {
if (typeof data.email !== "undefined") { if (isDefined(data.email)) {
const customer = await this.createOrFetchUserFromEmail_(data.email) const customer = await this.createOrFetchUserFromEmail_(data.email)
cart.customer = customer cart.customer = customer
cart.customer_id = customer.id cart.customer_id = customer.id
@@ -866,14 +863,11 @@ class CartService extends TransactionBaseService<CartService> {
} }
} }
if ( if (isDefined(data.customer_id) || isDefined(data.region_id)) {
typeof data.customer_id !== "undefined" ||
typeof data.region_id !== "undefined"
) {
await this.updateUnitPrices_(cart, data.region_id, data.customer_id) await this.updateUnitPrices_(cart, data.region_id, data.customer_id)
} }
if (typeof data.region_id !== "undefined") { if (isDefined(data.region_id)) {
const shippingAddress = const shippingAddress =
typeof data.shipping_address !== "string" typeof data.shipping_address !== "string"
? data.shipping_address ? data.shipping_address
@@ -902,7 +896,7 @@ class CartService extends TransactionBaseService<CartService> {
this.featureFlagRouter_.isFeatureEnabled(SalesChannelFeatureFlag.key) this.featureFlagRouter_.isFeatureEnabled(SalesChannelFeatureFlag.key)
) { ) {
if ( if (
typeof data.sales_channel_id !== "undefined" && isDefined(data.sales_channel_id) &&
data.sales_channel_id != cart.sales_channel_id data.sales_channel_id != cart.sales_channel_id
) { ) {
await this.onSalesChannelChange(cart, data.sales_channel_id) await this.onSalesChannelChange(cart, data.sales_channel_id)
@@ -910,7 +904,7 @@ class CartService extends TransactionBaseService<CartService> {
} }
} }
if (typeof data.discounts !== "undefined") { if (isDefined(data.discounts)) {
const previousDiscounts = [...cart.discounts] const previousDiscounts = [...cart.discounts]
cart.discounts.length = 0 cart.discounts.length = 0
+2 -2
View File
@@ -25,7 +25,7 @@ import { LineItemRepository } from "../repositories/line-item"
import { MedusaError } from "medusa-core-utils" import { MedusaError } from "medusa-core-utils"
import { ShippingMethodRepository } from "../repositories/shipping-method" import { ShippingMethodRepository } from "../repositories/shipping-method"
import { TransactionBaseService } from "../interfaces" import { TransactionBaseService } from "../interfaces"
import { buildQuery, setMetadata } from "../utils" import { buildQuery, isDefined, setMetadata } from "../utils"
import { FindConfig } from "../types/common" import { FindConfig } from "../types/common"
import { CreateClaimInput, UpdateClaimInput } from "../types/claim" import { CreateClaimInput, UpdateClaimInput } from "../types/claim"
@@ -336,7 +336,7 @@ export default class ClaimService extends TransactionBaseService<
} }
let newItems: LineItem[] = [] let newItems: LineItem[] = []
if (typeof additional_items !== "undefined") { if (isDefined(additional_items)) {
for (const item of additional_items) { for (const item of additional_items) {
await this.inventoryService_ await this.inventoryService_
.withTransaction(transactionManager) .withTransaction(transactionManager)
@@ -9,6 +9,7 @@ import {
CustomerGroupUpdate, CustomerGroupUpdate,
FilterableCustomerGroupProps, FilterableCustomerGroupProps,
} from "../types/customer-groups" } from "../types/customer-groups"
import { isDefined } from "../utils"
import { formatException } from "../utils/exception-formatter" import { formatException } from "../utils/exception-formatter"
type CustomerGroupConstructorProps = { type CustomerGroupConstructorProps = {
@@ -173,12 +174,12 @@ class CustomerGroupService extends BaseService {
const customerGroup = await this.retrieve(customerGroupId) const customerGroup = await this.retrieve(customerGroupId)
for (const key in properties) { for (const key in properties) {
if (typeof properties[key] !== "undefined") { if (isDefined(properties[key])) {
customerGroup[key] = properties[key] customerGroup[key] = properties[key]
} }
} }
if (typeof metadata !== "undefined") { if (isDefined(metadata)) {
customerGroup.metadata = this.setMetadata_(customerGroup, metadata) customerGroup.metadata = this.setMetadata_(customerGroup, metadata)
} }
return await cgRepo.save(customerGroup) return await cgRepo.save(customerGroup)
+3 -3
View File
@@ -9,7 +9,7 @@ import { AddressRepository } from "../repositories/address"
import { CustomerRepository } from "../repositories/customer" import { CustomerRepository } from "../repositories/customer"
import { AddressCreatePayload, FindConfig, Selector } from "../types/common" import { AddressCreatePayload, FindConfig, Selector } from "../types/common"
import { CreateCustomerInput, UpdateCustomerInput } from "../types/customers" import { CreateCustomerInput, UpdateCustomerInput } from "../types/customers"
import { buildQuery, setMetadata } from "../utils" import { buildQuery, isDefined, setMetadata } from "../utils"
import { formatException } from "../utils/exception-formatter" import { formatException } from "../utils/exception-formatter"
import EventBusService from "./event-bus" import EventBusService from "./event-bus"
@@ -324,7 +324,7 @@ class CustomerService extends TransactionBaseService<CustomerService> {
if ("billing_address_id" in update || "billing_address" in update) { if ("billing_address_id" in update || "billing_address" in update) {
const address = billing_address_id || billing_address const address = billing_address_id || billing_address
if (typeof address !== "undefined") { if (isDefined(address)) {
await this.updateBillingAddress_(customer, address) await this.updateBillingAddress_(customer, address)
} }
} }
@@ -395,7 +395,7 @@ class CustomerService extends TransactionBaseService<CustomerService> {
address.country_code = address.country_code?.toLowerCase() address.country_code = address.country_code?.toLowerCase()
if (typeof address?.id !== "undefined") { if (isDefined(address?.id)) {
customer.billing_address_id = address.id customer.billing_address_id = address.id
} else { } else {
if (customer.billing_address_id) { if (customer.billing_address_id) {
+2 -2
View File
@@ -13,7 +13,7 @@ import {
FulfillmentItemPartition, FulfillmentItemPartition,
FulFillmentItemType, FulFillmentItemType,
} from "../types/fulfillment" } from "../types/fulfillment"
import { buildQuery } from "../utils" import { buildQuery, isDefined } from "../utils"
import FulfillmentProviderService from "./fulfillment-provider" import FulfillmentProviderService from "./fulfillment-provider"
import LineItemService from "./line-item" import LineItemService from "./line-item"
import TotalsService from "./totals" import TotalsService from "./totals"
@@ -336,7 +336,7 @@ class FulfillmentService extends TransactionBaseService<FulfillmentService> {
trackingLinkRepo.create(tl) trackingLinkRepo.create(tl)
) )
if (typeof no_notification !== "undefined") { if (isDefined(no_notification)) {
fulfillment.no_notification = no_notification fulfillment.no_notification = no_notification
} }
+4 -4
View File
@@ -17,7 +17,7 @@ import {
CreateGiftCardTransactionInput, CreateGiftCardTransactionInput,
UpdateGiftCardInput, UpdateGiftCardInput,
} from "../types/gift-card" } from "../types/gift-card"
import { buildQuery, setMetadata } from "../utils" import { buildQuery, isDefined, setMetadata } from "../utils"
import RegionService from "./region" import RegionService from "./region"
type InjectedDependencies = { type InjectedDependencies = {
@@ -89,7 +89,7 @@ class GiftCardService extends TransactionBaseService<GiftCardService> {
const giftCardRepo = manager.getCustomRepository(this.giftCardRepository_) const giftCardRepo = manager.getCustomRepository(this.giftCardRepository_)
let q: string | undefined let q: string | undefined
if (typeof selector.q !== "undefined") { if (isDefined(selector.q)) {
q = selector.q q = selector.q
delete selector.q delete selector.q
} }
@@ -118,7 +118,7 @@ class GiftCardService extends TransactionBaseService<GiftCardService> {
const giftCardRepo = manager.getCustomRepository(this.giftCardRepository_) const giftCardRepo = manager.getCustomRepository(this.giftCardRepository_)
let q: string | undefined let q: string | undefined
if (typeof selector.q !== "undefined") { if (isDefined(selector.q)) {
q = selector.q q = selector.q
delete selector.q delete selector.q
} }
@@ -255,7 +255,7 @@ class GiftCardService extends TransactionBaseService<GiftCardService> {
giftCard.metadata = setMetadata(giftCard, metadata) giftCard.metadata = setMetadata(giftCard, metadata)
} }
if (typeof balance !== "undefined") { if (isDefined(balance)) {
if (balance < 0 || giftCard.value < balance) { if (balance < 0 || giftCard.value < balance) {
throw new MedusaError( throw new MedusaError(
MedusaError.Types.INVALID_ARGUMENT, MedusaError.Types.INVALID_ARGUMENT,
@@ -27,6 +27,7 @@ import {
ProductVariantPrice, ProductVariantPrice,
UpdateProductVariantInput, UpdateProductVariantInput,
} from "../types/product-variant" } from "../types/product-variant"
import { isDefined } from "../utils"
/** /**
* Provides layer to manipulate product variants. * Provides layer to manipulate product variants.
@@ -751,7 +752,7 @@ class ProductVariantService extends BaseService {
config: FindConfig<ProductVariant> config: FindConfig<ProductVariant>
): { query: FindWithRelationsOptions; relations: string[]; q?: string } { ): { query: FindWithRelationsOptions; relations: string[]; q?: string } {
let q: string | undefined let q: string | undefined
if (typeof selector.q !== "undefined") { if (isDefined(selector.q)) {
q = selector.q q = selector.q
delete selector.q delete selector.q
} }
+5 -5
View File
@@ -29,7 +29,7 @@ import {
ProductOptionInput, ProductOptionInput,
UpdateProductInput, UpdateProductInput,
} from "../types/product" } from "../types/product"
import { buildQuery, setMetadata } from "../utils" import { buildQuery, isDefined, setMetadata } from "../utils"
import { formatException } from "../utils/exception-formatter" import { formatException } from "../utils/exception-formatter"
import EventBusService from "./event-bus" import EventBusService from "./event-bus"
@@ -393,7 +393,7 @@ class ProductService extends TransactionBaseService<
if ( if (
this.featureFlagRouter_.isFeatureEnabled(SalesChannelFeatureFlag.key) this.featureFlagRouter_.isFeatureEnabled(SalesChannelFeatureFlag.key)
) { ) {
if (typeof salesChannels !== "undefined") { if (isDefined(salesChannels)) {
product.sales_channels = [] product.sales_channels = []
if (salesChannels?.length) { if (salesChannels?.length) {
const salesChannelIds = salesChannels?.map((sc) => sc.id) const salesChannelIds = salesChannels?.map((sc) => sc.id)
@@ -464,11 +464,11 @@ class ProductService extends TransactionBaseService<
if ( if (
this.featureFlagRouter_.isFeatureEnabled(SalesChannelFeatureFlag.key) this.featureFlagRouter_.isFeatureEnabled(SalesChannelFeatureFlag.key)
) { ) {
if (typeof update.sales_channels !== "undefined") { if (isDefined(update.sales_channels)) {
relations.push("sales_channels") relations.push("sales_channels")
} }
} else { } else {
if (typeof update.sales_channels !== "undefined") { if (isDefined(update.sales_channels)) {
throw new MedusaError( throw new MedusaError(
MedusaError.Types.INVALID_DATA, MedusaError.Types.INVALID_DATA,
"the property sales_channels should no appears as part of the payload" "the property sales_channels should no appears as part of the payload"
@@ -513,7 +513,7 @@ class ProductService extends TransactionBaseService<
if ( if (
this.featureFlagRouter_.isFeatureEnabled(SalesChannelFeatureFlag.key) this.featureFlagRouter_.isFeatureEnabled(SalesChannelFeatureFlag.key)
) { ) {
if (typeof salesChannels !== "undefined") { if (isDefined(salesChannels)) {
product.sales_channels = [] product.sales_channels = []
if (salesChannels?.length) { if (salesChannels?.length) {
const salesChannelIds = salesChannels?.map((sc) => sc.id) const salesChannelIds = salesChannels?.map((sc) => sc.id)
+2 -1
View File
@@ -1,5 +1,6 @@
import { MedusaError } from "medusa-core-utils" import { MedusaError } from "medusa-core-utils"
import { BaseService } from "medusa-interfaces" import { BaseService } from "medusa-interfaces"
import { isDefined } from "../utils"
/** /**
* Handles Returns * Handles Returns
@@ -357,7 +358,7 @@ class ReturnService extends BaseService {
) )
let toRefund = data.refund_amount let toRefund = data.refund_amount
if (typeof toRefund !== "undefined") { if (isDefined(toRefund)) {
// Merchant wants to do a custom refund amount; we check if amount is // Merchant wants to do a custom refund amount; we check if amount is
// refundable // refundable
const refundable = order.refundable_amount const refundable = order.refundable_amount
+10 -13
View File
@@ -19,7 +19,7 @@ import {
UpdateShippingOptionInput, UpdateShippingOptionInput,
CreateShippingOptionInput, CreateShippingOptionInput,
} from "../types/shipping-options" } from "../types/shipping-options"
import { buildQuery, setMetadata } from "../utils" import { buildQuery, isDefined, setMetadata } from "../utils"
import FulfillmentProviderService from "./fulfillment-provider" import FulfillmentProviderService from "./fulfillment-provider"
import RegionService from "./region" import RegionService from "./region"
@@ -262,7 +262,7 @@ class ShippingOptionService extends TransactionBaseService<ShippingOptionService
const methodRepo = manager.getCustomRepository(this.methodRepository_) const methodRepo = manager.getCustomRepository(this.methodRepository_)
if (typeof config.cart !== "undefined") { if (isDefined(config.cart)) {
await this.validateCartOption(option, config.cart) await this.validateCartOption(option, config.cart)
} }
@@ -414,7 +414,7 @@ class ShippingOptionService extends TransactionBaseService<ShippingOptionService
) )
} }
if (typeof data.requirements !== "undefined") { if (isDefined(data.requirements)) {
const acc: ShippingOptionRequirement[] = [] const acc: ShippingOptionRequirement[] = []
for (const r of data.requirements) { for (const r of data.requirements) {
const validated = await this.validateRequirement_(r) const validated = await this.validateRequirement_(r)
@@ -500,7 +500,7 @@ class ShippingOptionService extends TransactionBaseService<ShippingOptionService
relations: ["requirements"], relations: ["requirements"],
}) })
if (typeof update.metadata !== "undefined") { if (isDefined(update.metadata)) {
option.metadata = await setMetadata(option, update.metadata) option.metadata = await setMetadata(option, update.metadata)
} }
@@ -511,14 +511,14 @@ class ShippingOptionService extends TransactionBaseService<ShippingOptionService
) )
} }
if (typeof update.is_return !== "undefined") { if (isDefined(update.is_return)) {
throw new MedusaError( throw new MedusaError(
MedusaError.Types.NOT_ALLOWED, MedusaError.Types.NOT_ALLOWED,
"is_return cannot be changed after creation" "is_return cannot be changed after creation"
) )
} }
if (typeof update.requirements !== "undefined") { if (isDefined(update.requirements)) {
const acc: ShippingOptionRequirement[] = [] const acc: ShippingOptionRequirement[] = []
for (const r of update.requirements) { for (const r of update.requirements) {
const validated = await this.validateRequirement_(r, optionId) const validated = await this.validateRequirement_(r, optionId)
@@ -562,7 +562,7 @@ class ShippingOptionService extends TransactionBaseService<ShippingOptionService
option.requirements = acc option.requirements = acc
} }
if (typeof update.price_type !== "undefined") { if (isDefined(update.price_type)) {
option.price_type = await this.validatePriceType_( option.price_type = await this.validatePriceType_(
update.price_type, update.price_type,
option option
@@ -572,18 +572,15 @@ class ShippingOptionService extends TransactionBaseService<ShippingOptionService
} }
} }
if ( if (isDefined(update.amount) && option.price_type !== "calculated") {
typeof update.amount !== "undefined" &&
option.price_type !== "calculated"
) {
option.amount = update.amount option.amount = update.amount
} }
if (typeof update.name !== "undefined") { if (isDefined(update.name)) {
option.name = update.name option.name = update.name
} }
if (typeof update.admin_only !== "undefined") { if (isDefined(update.admin_only)) {
option.admin_only = update.admin_only option.admin_only = update.admin_only
} }
+3 -2
View File
@@ -1,5 +1,6 @@
import { MedusaError } from "medusa-core-utils" import { MedusaError } from "medusa-core-utils"
import { BaseService } from "medusa-interfaces" import { BaseService } from "medusa-interfaces"
import { isDefined } from "../utils"
/** /**
* Handles swaps * Handles swaps
@@ -117,7 +118,7 @@ class SwapService extends BaseService {
let cartSelects = null let cartSelects = null
let cartRelations = null let cartRelations = null
if (typeof relations !== "undefined" && relations.includes("cart")) { if (isDefined(relations) && relations.includes("cart")) {
const [swapRelations, cartRels] = relations.reduce( const [swapRelations, cartRels] = relations.reduce(
(acc, next) => { (acc, next) => {
if (next === "cart") { if (next === "cart") {
@@ -140,7 +141,7 @@ class SwapService extends BaseService {
cartRelations = cartRels cartRelations = cartRels
let foundCartId = false let foundCartId = false
if (typeof select !== "undefined") { if (isDefined(select)) {
const [swapSelects, cartSels] = select.reduce( const [swapSelects, cartSels] = select.reduce(
(acc, next) => { (acc, next) => {
if (next.startsWith("cart.")) { if (next.startsWith("cart.")) {
+2 -1
View File
@@ -16,6 +16,7 @@ import {
TaxRateListByConfig, TaxRateListByConfig,
UpdateTaxRateInput, UpdateTaxRateInput,
} from "../types/tax-rate" } from "../types/tax-rate"
import { isDefined } from "../utils"
class TaxRateService extends BaseService { class TaxRateService extends BaseService {
private manager_: EntityManager private manager_: EntityManager
@@ -122,7 +123,7 @@ class TaxRateService extends BaseService {
const taxRate = await this.retrieve(id) const taxRate = await this.retrieve(id)
for (const [k, v] of Object.entries(data)) { for (const [k, v] of Object.entries(data)) {
if (typeof v !== "undefined") { if (isDefined(v)) {
taxRate[k] = v taxRate[k] = v
} }
} }
+3 -2
View File
@@ -23,6 +23,7 @@ import {
} from "../types/totals" } from "../types/totals"
import TaxProviderService from "./tax-provider" import TaxProviderService from "./tax-provider"
import { EntityManager } from "typeorm" import { EntityManager } from "typeorm"
import { isDefined } from "../utils"
type ShippingMethodTotals = { type ShippingMethodTotals = {
price: number price: number
@@ -315,8 +316,8 @@ class TotalsService extends TransactionBaseService<TotalsService> {
let taxLines: (ShippingMethodTaxLine | LineItemTaxLine)[] let taxLines: (ShippingMethodTaxLine | LineItemTaxLine)[]
if (isOrder(cartOrOrder)) { if (isOrder(cartOrOrder)) {
const taxLinesJoined = cartOrOrder.items.every( const taxLinesJoined = cartOrOrder.items.every((i) =>
(i) => typeof i.tax_lines !== "undefined" isDefined(i.tax_lines)
) )
if (!taxLinesJoined) { if (!taxLinesJoined) {
throw new MedusaError( throw new MedusaError(
@@ -7,6 +7,7 @@ import {
} from "../interfaces/price-selection-strategy" } from "../interfaces/price-selection-strategy"
import { MoneyAmountRepository } from "../repositories/money-amount" import { MoneyAmountRepository } from "../repositories/money-amount"
import { EntityManager } from "typeorm" import { EntityManager } from "typeorm"
import { isDefined } from "../utils"
class PriceSelectionStrategy extends AbstractPriceSelectionStrategy { class PriceSelectionStrategy extends AbstractPriceSelectionStrategy {
private moneyAmountRepository_: typeof MoneyAmountRepository private moneyAmountRepository_: typeof MoneyAmountRepository
@@ -103,8 +104,7 @@ class PriceSelectionStrategy extends AbstractPriceSelectionStrategy {
} }
const isValidQuantity = (price, quantity): boolean => const isValidQuantity = (price, quantity): boolean =>
(typeof quantity !== "undefined" && (isDefined(quantity) && isValidPriceWithQuantity(price, quantity)) ||
isValidPriceWithQuantity(price, quantity)) ||
(typeof quantity === "undefined" && isValidPriceWithoutQuantity(price)) (typeof quantity === "undefined" && isValidPriceWithoutQuantity(price))
const isValidPriceWithoutQuantity = (price): boolean => const isValidPriceWithoutQuantity = (price): boolean =>
@@ -2,6 +2,7 @@ import { pick } from "lodash"
import { FindConfig, QueryConfig, RequestQueryFields } from "../types/common" import { FindConfig, QueryConfig, RequestQueryFields } from "../types/common"
import { MedusaError } from "medusa-core-utils/dist" import { MedusaError } from "medusa-core-utils/dist"
import { BaseEntity } from "../interfaces/models/base-entity" import { BaseEntity } from "../interfaces/models/base-entity"
import { isDefined } from "."
export function pickByConfig<TModel extends BaseEntity>( export function pickByConfig<TModel extends BaseEntity>(
obj: TModel | TModel[], obj: TModel | TModel[],
@@ -26,14 +27,14 @@ export function getRetrieveConfig<TModel extends BaseEntity>(
expand?: string[] expand?: string[]
): FindConfig<TModel> { ): FindConfig<TModel> {
let includeFields: (keyof TModel)[] = [] let includeFields: (keyof TModel)[] = []
if (typeof fields !== "undefined") { if (isDefined(fields)) {
includeFields = Array.from(new Set([...fields, "id"])).map((field) => includeFields = Array.from(new Set([...fields, "id"])).map((field) =>
typeof field === "string" ? field.trim() : field typeof field === "string" ? field.trim() : field
) as (keyof TModel)[] ) as (keyof TModel)[]
} }
let expandFields: string[] = [] let expandFields: string[] = []
if (typeof expand !== "undefined") { if (isDefined(expand)) {
expandFields = expand.map((expandRelation) => expandRelation.trim()) expandFields = expand.map((expandRelation) => expandRelation.trim())
} }
@@ -53,7 +54,7 @@ export function getListConfig<TModel extends BaseEntity>(
order?: { [k: symbol]: "DESC" | "ASC" } order?: { [k: symbol]: "DESC" | "ASC" }
): FindConfig<TModel> { ): FindConfig<TModel> {
let includeFields: (keyof TModel)[] = [] let includeFields: (keyof TModel)[] = []
if (typeof fields !== "undefined") { if (isDefined(fields)) {
const fieldSet = new Set(fields) const fieldSet = new Set(fields)
// Ensure created_at is included, since we are sorting on this // Ensure created_at is included, since we are sorting on this
fieldSet.add("created_at") fieldSet.add("created_at")
@@ -62,7 +63,7 @@ export function getListConfig<TModel extends BaseEntity>(
} }
let expandFields: string[] = [] let expandFields: string[] = []
if (typeof expand !== "undefined") { if (isDefined(expand)) {
expandFields = expand expandFields = expand
} }
@@ -96,7 +97,7 @@ export function prepareListQuery<
} }
let orderBy: { [k: symbol]: "DESC" | "ASC" } | undefined let orderBy: { [k: symbol]: "DESC" | "ASC" } | undefined
if (typeof order !== "undefined") { if (isDefined(order)) {
let orderField = order let orderField = order
if (order.startsWith("-")) { if (order.startsWith("-")) {
const [, field] = order.split("-") const [, field] = order.split("-")
+1
View File
@@ -3,3 +3,4 @@ export * from "./set-metadata"
export * from "./validate-id" export * from "./validate-id"
export * from "./generate-entity-id" export * from "./generate-entity-id"
export * from "./remove-undefined-properties" export * from "./remove-undefined-properties"
export * from "./is-defined"
+3
View File
@@ -0,0 +1,3 @@
export function isDefined<T = undefined | unknown>(val: T): val is (T extends undefined ? never : T) {
return typeof val !== "undefined"
}
@@ -1,3 +1,5 @@
import { isDefined } from "./is-defined";
export function removeUndefinedProperties<T extends object>(inputObj: T): T { export function removeUndefinedProperties<T extends object>(inputObj: T): T {
const removeProperties = (obj: T) => { const removeProperties = (obj: T) => {
const res = {} as T const res = {} as T
@@ -17,13 +19,13 @@ export function removeUndefinedProperties<T extends object>(inputObj: T): T {
} }
function removeUndefinedDeeply(input: unknown): any { function removeUndefinedDeeply(input: unknown): any {
if (typeof input !== "undefined") { if (isDefined(input)) {
if (input === null || input === "null") { if (input === null || input === "null") {
return null return null
} else if (Array.isArray(input)) { } else if (Array.isArray(input)) {
return input.map((item) => { return input.map((item) => {
return removeUndefinedDeeply(item) return removeUndefinedDeeply(item)
}).filter(v => typeof v !== "undefined") }).filter(v => isDefined(v))
} else if (Object.prototype.toString.call(input) === '[object Date]') { } else if (Object.prototype.toString.call(input) === '[object Date]') {
return input return input
} else if (typeof input === "object") { } else if (typeof input === "object") {