From c31290c911450a06d5e4da3dc5e4e3977071a6ea Mon Sep 17 00:00:00 2001 From: Adrien de Peretti Date: Wed, 10 Aug 2022 17:45:48 +0200 Subject: [PATCH] feat(medusa): Refactor undefined check into a single util (#2024) --- .changeset/tiny-sheep-compare.md | 5 ++++ .../api/routes/admin/batch/list-batch-jobs.ts | 6 ++--- .../routes/admin/discounts/list-discounts.ts | 3 ++- .../admin/gift-cards/list-gift-cards.ts | 3 ++- .../api/routes/admin/orders/request-return.ts | 3 ++- .../price-lists/list-price-list-products.ts | 3 ++- .../admin/product-tags/list-product-tags.ts | 3 ++- .../admin/product-types/list-product-types.ts | 3 ++- .../routes/admin/returns/receive-return.ts | 3 ++- .../routes/admin/tax-rates/create-tax-rate.ts | 7 +++--- .../routes/admin/tax-rates/update-tax-rate.ts | 7 +++--- .../admin/tax-rates/utils/get-query-config.ts | 9 ++++---- .../src/api/routes/store/carts/create-cart.ts | 8 +++---- .../routes/store/products/list-products.ts | 3 ++- .../controllers/customers/list-customers.ts | 3 ++- .../medusa/src/loaders/feature-flags/index.ts | 5 ++-- packages/medusa/src/loaders/services.ts | 3 ++- packages/medusa/src/loaders/strategies.ts | 4 ++-- packages/medusa/src/repositories/tax-rate.ts | 5 ++-- packages/medusa/src/services/cart.ts | 22 +++++++----------- packages/medusa/src/services/claim.ts | 4 ++-- .../medusa/src/services/customer-group.ts | 5 ++-- packages/medusa/src/services/customer.ts | 6 ++--- packages/medusa/src/services/fulfillment.ts | 4 ++-- packages/medusa/src/services/gift-card.ts | 8 +++---- .../medusa/src/services/product-variant.ts | 3 ++- packages/medusa/src/services/product.ts | 10 ++++---- packages/medusa/src/services/return.js | 3 ++- .../medusa/src/services/shipping-option.ts | 23 ++++++++----------- packages/medusa/src/services/swap.js | 5 ++-- packages/medusa/src/services/tax-rate.ts | 3 ++- packages/medusa/src/services/totals.ts | 5 ++-- .../medusa/src/strategies/price-selection.ts | 4 ++-- packages/medusa/src/utils/get-query-config.ts | 11 +++++---- packages/medusa/src/utils/index.ts | 1 + packages/medusa/src/utils/is-defined.ts | 3 +++ .../src/utils/remove-undefined-properties.ts | 6 +++-- 37 files changed, 118 insertions(+), 94 deletions(-) create mode 100644 .changeset/tiny-sheep-compare.md create mode 100644 packages/medusa/src/utils/is-defined.ts diff --git a/.changeset/tiny-sheep-compare.md b/.changeset/tiny-sheep-compare.md new file mode 100644 index 0000000000..0fc8f082ef --- /dev/null +++ b/.changeset/tiny-sheep-compare.md @@ -0,0 +1,5 @@ +--- +"@medusajs/medusa": patch +--- + +Add new `isDefined` utility diff --git a/packages/medusa/src/api/routes/admin/batch/list-batch-jobs.ts b/packages/medusa/src/api/routes/admin/batch/list-batch-jobs.ts index d8a863dffb..2360fc801d 100644 --- a/packages/medusa/src/api/routes/admin/batch/list-batch-jobs.ts +++ b/packages/medusa/src/api/routes/admin/batch/list-batch-jobs.ts @@ -6,6 +6,7 @@ import { DateComparisonOperator } from "../../../../types/common" import { IsType } from "../../../../utils/validators/is-type" import { Request } from "express" import { pickBy } from "lodash" +import { isDefined } from "../../../../utils" /** * @oas [get] /batch-jobs @@ -238,9 +239,8 @@ export default async (req: Request, res) => { const created_by = req.user?.id || req.user?.userId const [jobs, count] = await batchService.listAndCount( - pickBy( - { created_by, ...(req.filterableFields ?? {}) }, - (val) => typeof val !== "undefined" + pickBy({ created_by, ...(req.filterableFields ?? {}) }, (val) => + isDefined(val) ), req.listConfig ) diff --git a/packages/medusa/src/api/routes/admin/discounts/list-discounts.ts b/packages/medusa/src/api/routes/admin/discounts/list-discounts.ts index 9fc7a351ce..7a725db09a 100644 --- a/packages/medusa/src/api/routes/admin/discounts/list-discounts.ts +++ b/packages/medusa/src/api/routes/admin/discounts/list-discounts.ts @@ -14,6 +14,7 @@ import { Discount } from "../../../.." import DiscountService from "../../../../services/discount" import { FindConfig } from "../../../../types/common" import { validator } from "../../../../utils/validator" +import { isDefined } from "../../../../utils" /** * @oas [get] /discounts @@ -84,7 +85,7 @@ export default async (req, res) => { const filterableFields = _.omit(validated, ["limit", "offset", "expand"]) const [discounts, count] = await discountService.listAndCount( - pickBy(filterableFields, (val) => typeof val !== "undefined"), + pickBy(filterableFields, (val) => isDefined(val)), listConfig ) diff --git a/packages/medusa/src/api/routes/admin/gift-cards/list-gift-cards.ts b/packages/medusa/src/api/routes/admin/gift-cards/list-gift-cards.ts index 897732cd82..fb1e373337 100644 --- a/packages/medusa/src/api/routes/admin/gift-cards/list-gift-cards.ts +++ b/packages/medusa/src/api/routes/admin/gift-cards/list-gift-cards.ts @@ -4,6 +4,7 @@ import { GiftCardService } from "../../../../services" import { Type } from "class-transformer" import { pickBy } from "lodash" import { validator } from "../../../../utils/validator" +import { isDefined } from "../../../../utils" /** * @oas [get] /gift-cards @@ -44,7 +45,7 @@ export default async (req, res) => { const giftCardService: GiftCardService = req.scope.resolve("giftCardService") const [giftCards, count] = await giftCardService.listAndCount( - pickBy(req.filterableFields, (val) => typeof val !== "undefined"), + pickBy(req.filterableFields, (val) => isDefined(val)), req.listConfig ) diff --git a/packages/medusa/src/api/routes/admin/orders/request-return.ts b/packages/medusa/src/api/routes/admin/orders/request-return.ts index a79d5fc7c0..afae0127d6 100644 --- a/packages/medusa/src/api/routes/admin/orders/request-return.ts +++ b/packages/medusa/src/api/routes/admin/orders/request-return.ts @@ -18,6 +18,7 @@ import { OrdersReturnItem } from "../../../../types/orders" import { Type } from "class-transformer" import { validator } from "../../../../utils/validator" import { EntityManager } from "typeorm" +import { isDefined } from "../../../../utils" /** * @oas [post] /orders/{id}/return @@ -140,7 +141,7 @@ export default async (req, res) => { 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 } else { if (value.refund && value.refund >= 0) { diff --git a/packages/medusa/src/api/routes/admin/price-lists/list-price-list-products.ts b/packages/medusa/src/api/routes/admin/price-lists/list-price-list-products.ts index 02d326f7ca..ea7deb266c 100644 --- a/packages/medusa/src/api/routes/admin/price-lists/list-price-list-products.ts +++ b/packages/medusa/src/api/routes/admin/price-lists/list-price-list-products.ts @@ -17,6 +17,7 @@ import { ProductStatus } from "../../../../models" import { Request } from "express" import { Type } from "class-transformer" import { pickBy } from "lodash" +import { isDefined } from "../../../../utils" /** * @oas [get] /price-lists/:id/products @@ -168,7 +169,7 @@ export default async (req: Request, res) => { const [products, count] = await priceListService.listProducts( id, - pickBy(filterableFields, (val) => typeof val !== "undefined"), + pickBy(filterableFields, (val) => isDefined(val)), req.listConfig ) diff --git a/packages/medusa/src/api/routes/admin/product-tags/list-product-tags.ts b/packages/medusa/src/api/routes/admin/product-tags/list-product-tags.ts index f4dbafe5e9..a4757cdf54 100644 --- a/packages/medusa/src/api/routes/admin/product-tags/list-product-tags.ts +++ b/packages/medusa/src/api/routes/admin/product-tags/list-product-tags.ts @@ -17,6 +17,7 @@ import { ProductTag } from "../../../../models/product-tag" import ProductTagService from "../../../../services/product-tag" import { Type } from "class-transformer" import { validator } from "../../../../utils/validator" +import { isDefined } from "../../../../utils" /** * @oas [get] /product-tags @@ -124,7 +125,7 @@ export default async (req, res) => { take: validated.limit, } - if (typeof validated.order !== "undefined") { + if (isDefined(validated.order)) { let orderField = validated.order if (validated.order.startsWith("-")) { const [, field] = validated.order.split("-") diff --git a/packages/medusa/src/api/routes/admin/product-types/list-product-types.ts b/packages/medusa/src/api/routes/admin/product-types/list-product-types.ts index 8fe0d9260c..84f6e69fbd 100644 --- a/packages/medusa/src/api/routes/admin/product-types/list-product-types.ts +++ b/packages/medusa/src/api/routes/admin/product-types/list-product-types.ts @@ -17,6 +17,7 @@ import { ProductType } from "../../../../models/product-type" import ProductTypeService from "../../../../services/product-type" import { Type } from "class-transformer" import { validator } from "../../../../utils/validator" +import { isDefined } from "../../../../utils" /** * @oas [get] /product-types @@ -125,7 +126,7 @@ export default async (req, res) => { take: validated.limit, } - if (typeof validated.order !== "undefined") { + if (isDefined(validated.order)) { let orderField = validated.order if (validated.order.startsWith("-")) { const [, field] = validated.order.split("-") diff --git a/packages/medusa/src/api/routes/admin/returns/receive-return.ts b/packages/medusa/src/api/routes/admin/returns/receive-return.ts index 10e7633c69..c804a95460 100644 --- a/packages/medusa/src/api/routes/admin/returns/receive-return.ts +++ b/packages/medusa/src/api/routes/admin/returns/receive-return.ts @@ -10,6 +10,7 @@ import { OrderService, ReturnService, SwapService } from "../../../../services" import { EntityManager } from "typeorm" import { Type } from "class-transformer" import { validator } from "../../../../utils/validator" +import { isDefined } from "../../../../utils" /** * @oas [post] /returns/{id}/receive @@ -68,7 +69,7 @@ export default async (req, res) => { await entityManager.transaction(async (manager) => { let refundAmount = validated.refund - if (typeof validated.refund !== "undefined" && validated.refund < 0) { + if (isDefined(validated.refund) && validated.refund < 0) { refundAmount = 0 } diff --git a/packages/medusa/src/api/routes/admin/tax-rates/create-tax-rate.ts b/packages/medusa/src/api/routes/admin/tax-rates/create-tax-rate.ts index 145a0958b6..6ad7a5fb74 100644 --- a/packages/medusa/src/api/routes/admin/tax-rates/create-tax-rate.ts +++ b/packages/medusa/src/api/routes/admin/tax-rates/create-tax-rate.ts @@ -8,6 +8,7 @@ import { TaxRate } from "../../../.." import { TaxRateService } from "../../../../services" import { omit } from "lodash" import { validator } from "../../../../utils/validator" +import { isDefined } from "../../../../utils" /** * @oas [post] /tax-rates @@ -98,15 +99,15 @@ export default async (req, res) => { ) id = created.id - if (typeof value.products !== "undefined") { + if (isDefined(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) } - if (typeof value.shipping_options !== "undefined") { + if (isDefined(value.shipping_options)) { await txRateService.addToShippingOption(id, value.shipping_options) } }) diff --git a/packages/medusa/src/api/routes/admin/tax-rates/update-tax-rate.ts b/packages/medusa/src/api/routes/admin/tax-rates/update-tax-rate.ts index 2ed36a16e0..d7479f7631 100644 --- a/packages/medusa/src/api/routes/admin/tax-rates/update-tax-rate.ts +++ b/packages/medusa/src/api/routes/admin/tax-rates/update-tax-rate.ts @@ -7,6 +7,7 @@ import { TaxRate } from "../../../.." import { TaxRateService } from "../../../../services" import { omit } from "lodash" import { validator } from "../../../../utils/validator" +import { isDefined } from "../../../../utils" /** * @oas [post] /tax-rates/:id @@ -92,11 +93,11 @@ export default async (req, res) => { 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) } - if (typeof value.product_types !== "undefined") { + if (isDefined(value.product_types)) { await txRateService.addToProductType( req.params.id, 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( req.params.id, value.shipping_options, diff --git a/packages/medusa/src/api/routes/admin/tax-rates/utils/get-query-config.ts b/packages/medusa/src/api/routes/admin/tax-rates/utils/get-query-config.ts index caf1bf80e1..36e1952631 100644 --- a/packages/medusa/src/api/routes/admin/tax-rates/utils/get-query-config.ts +++ b/packages/medusa/src/api/routes/admin/tax-rates/utils/get-query-config.ts @@ -2,6 +2,7 @@ import { pick } from "lodash" import { defaultAdminTaxRatesFields, defaultAdminTaxRatesRelations } from "../" import { TaxRate } from "../../../../.." import { FindConfig } from "../../../../../types/common" +import { isDefined } from "../../../../../utils" export function pickByConfig( obj: T | T[], @@ -24,14 +25,14 @@ export function getRetrieveConfig( expand?: string[] ): FindConfig { let includeFields: (keyof TaxRate)[] = [] - if (typeof fields !== "undefined") { + if (isDefined(fields)) { const fieldSet = new Set(fields) fieldSet.add("id") includeFields = Array.from(fieldSet) as (keyof TaxRate)[] } let expandFields: string[] = [] - if (typeof expand !== "undefined") { + if (isDefined(expand)) { expandFields = expand } @@ -51,7 +52,7 @@ export function getListConfig( order?: { [k: symbol]: "DESC" | "ASC" } ): FindConfig { let includeFields: (keyof TaxRate)[] = [] - if (typeof fields !== "undefined") { + if (isDefined(fields)) { const fieldSet = new Set(fields) // Ensure created_at is included, since we are sorting on this fieldSet.add("created_at") @@ -60,7 +61,7 @@ export function getListConfig( } let expandFields: string[] = [] - if (typeof expand !== "undefined") { + if (isDefined(expand)) { expandFields = expand } diff --git a/packages/medusa/src/api/routes/store/carts/create-cart.ts b/packages/medusa/src/api/routes/store/carts/create-cart.ts index 76786e31ef..29cc39a6f6 100644 --- a/packages/medusa/src/api/routes/store/carts/create-cart.ts +++ b/packages/medusa/src/api/routes/store/carts/create-cart.ts @@ -1,7 +1,6 @@ import { CartService, LineItemService, RegionService } from "../../../../services" import { IsArray, - IsBoolean, IsInt, IsNotEmpty, IsOptional, @@ -19,6 +18,7 @@ import SalesChannelFeatureFlag from "../../../../loaders/feature-flags/sales-cha import { Type } from "class-transformer" import { decorateLineItemsWithTotals } from "./decorate-line-items-with-totals" import reqIp from "request-ip" +import { isDefined } from "../../../../utils"; /** * @oas [post] /carts @@ -91,9 +91,9 @@ export default async (req, res) => { const entityManager: EntityManager = req.scope.resolve("manager") const featureFlagRouter: FlagRouter = req.scope.resolve("featureFlagRouter") - let regionId: string - if (typeof validated.region_id !== "undefined") { - regionId = validated.region_id + let regionId!: string + if (isDefined(validated.region_id)) { + regionId = validated.region_id as string } else { const regions = await regionService.list({}) diff --git a/packages/medusa/src/api/routes/store/products/list-products.ts b/packages/medusa/src/api/routes/store/products/list-products.ts index 0ac75ac931..972556952f 100644 --- a/packages/medusa/src/api/routes/store/products/list-products.ts +++ b/packages/medusa/src/api/routes/store/products/list-products.ts @@ -22,6 +22,7 @@ import { Product } from "../../../../models" import { defaultStoreProductsRelations } from "." import { optionalBooleanMapper } from "../../../../utils/validators/is-boolean" import { validator } from "../../../../utils/validator" +import { isDefined } from "../../../../utils" /** * @oas [get] /products @@ -178,7 +179,7 @@ export default async (req, res) => { } const [rawProducts, count] = await productService.listAndCount( - pickBy(filterableFields, (val) => typeof val !== "undefined"), + pickBy(filterableFields, (val) => isDefined(val)), listConfig ) diff --git a/packages/medusa/src/controllers/customers/list-customers.ts b/packages/medusa/src/controllers/customers/list-customers.ts index 9253434308..f787086f81 100644 --- a/packages/medusa/src/controllers/customers/list-customers.ts +++ b/packages/medusa/src/controllers/customers/list-customers.ts @@ -5,6 +5,7 @@ import { CustomerService } from "../../services" import { FindConfig } from "../../types/common" import { validator } from "../../utils/validator" import { Customer } from "../../models/customer" +import { isDefined } from "../../utils" const listAndCount = async ( scope, @@ -33,7 +34,7 @@ const listAndCount = async ( ]) const [customers, count] = await customerService.listAndCount( - pickBy(filterableFields, (val) => typeof val !== "undefined"), + pickBy(filterableFields, (val) => isDefined(val)), listConfig ) diff --git a/packages/medusa/src/loaders/feature-flags/index.ts b/packages/medusa/src/loaders/feature-flags/index.ts index 5343019bd7..60874b43c4 100644 --- a/packages/medusa/src/loaders/feature-flags/index.ts +++ b/packages/medusa/src/loaders/feature-flags/index.ts @@ -5,6 +5,7 @@ import { trackFeatureFlag } from "medusa-telemetry" import { FlagSettings } from "../../types/feature-flags" import { Logger } from "../../types/global" import { FlagRouter } from "../../utils/flag-router" +import { isDefined } from "../../utils" const isTruthy = (val: string | boolean | undefined): boolean => { if (typeof val === "string") { @@ -36,10 +37,10 @@ export default ( flagConfig[flagSettings.key] = isTruthy(flagSettings.default_val) let from - if (typeof process.env[flagSettings.env_key] !== "undefined") { + if (isDefined(process.env[flagSettings.env_key])) { from = "environment" 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" flagConfig[flagSettings.key] = isTruthy( projectConfigFlags[flagSettings.key] diff --git a/packages/medusa/src/loaders/services.ts b/packages/medusa/src/loaders/services.ts index a97ea6604c..5b71c0a1b5 100644 --- a/packages/medusa/src/loaders/services.ts +++ b/packages/medusa/src/loaders/services.ts @@ -3,6 +3,7 @@ import path from "path" import { asFunction } from "awilix" import formatRegistrationName from "../utils/format-registration-name" import { ConfigModule, MedusaContainer } from "../types/global" +import { isDefined } from "../utils" type Options = { container: MedusaContainer; @@ -15,7 +16,7 @@ type Options = { */ export default ({ container, configModule, isTest }: Options): void => { 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 coreFull = path.join(__dirname, corePath) diff --git a/packages/medusa/src/loaders/strategies.ts b/packages/medusa/src/loaders/strategies.ts index 9063fcfef6..24028bbb02 100644 --- a/packages/medusa/src/loaders/strategies.ts +++ b/packages/medusa/src/loaders/strategies.ts @@ -5,6 +5,7 @@ import { asFunction, aliasTo } from "awilix" import formatRegistrationName from "../utils/format-registration-name" import { isBatchJobStrategy } from "../interfaces" import { MedusaContainer } from "../types/global" +import { isDefined } from "../utils" type LoaderOptions = { container: MedusaContainer @@ -17,8 +18,7 @@ type LoaderOptions = { * @returns void */ export default ({ container, configModule, isTest }: LoaderOptions): void => { - const useMock = - typeof isTest !== "undefined" ? isTest : process.env.NODE_ENV === "test" + const useMock = isDefined(isTest) ? isTest : process.env.NODE_ENV === "test" const corePath = useMock ? "../strategies/__mocks__/[!__]*.js" diff --git a/packages/medusa/src/repositories/tax-rate.ts b/packages/medusa/src/repositories/tax-rate.ts index 4536a93661..c70406a8db 100644 --- a/packages/medusa/src/repositories/tax-rate.ts +++ b/packages/medusa/src/repositories/tax-rate.ts @@ -16,6 +16,7 @@ import { ShippingTaxRate } from "../models/shipping-tax-rate" import { Product } from "../models/product" import { ShippingMethod } from "../models/shipping-method" import { TaxRateListByConfig } from "../types/tax-rate" +import { isDefined } from "../utils" const resolveableFields = [ "product_count", @@ -30,7 +31,7 @@ export class TaxRateRepository extends Repository { const cleanOptions = findOptions const resolverFields: string[] = [] - if (typeof findOptions.select !== "undefined") { + if (isDefined(findOptions.select)) { let selectableCols: (keyof TaxRate)[] = [] for (const k of findOptions.select) { if (!resolveableFields.includes(k)) { @@ -235,7 +236,7 @@ export class TaxRateRepository extends Repository { .leftJoin(Product, "prod", "prod.type_id = pttr.product_type_id") .where("prod.id = :productId", { productId }) - if (typeof config.region_id !== "undefined") { + if (isDefined(config.region_id)) { productRates.andWhere("txr.region_id = :regionId", { regionId: config.region_id, }) diff --git a/packages/medusa/src/services/cart.ts b/packages/medusa/src/services/cart.ts index 8caa2acdb4..96f2c06610 100644 --- a/packages/medusa/src/services/cart.ts +++ b/packages/medusa/src/services/cart.ts @@ -27,7 +27,7 @@ import { LineItemUpdate, } from "../types/cart" 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 CustomerService from "./customer" import DiscountService from "./discount" @@ -423,10 +423,7 @@ class CartService extends TransactionBaseService { ] for (const remainingField of remainingFields) { - if ( - typeof data[remainingField] !== "undefined" && - remainingField !== "object" - ) { + if (isDefined(data[remainingField]) && remainingField !== "object") { const key = remainingField as string rawCart[key] = data[remainingField] } @@ -448,7 +445,7 @@ class CartService extends TransactionBaseService { salesChannelId?: string ): Promise { let salesChannel: SalesChannel - if (typeof salesChannelId !== "undefined") { + if (isDefined(salesChannelId)) { salesChannel = await this.salesChannelService_ .withTransaction(this.manager_) .retrieve(salesChannelId) @@ -858,7 +855,7 @@ class CartService extends TransactionBaseService { if (data.customer_id) { await this.updateCustomerId_(cart, data.customer_id) } else { - if (typeof data.email !== "undefined") { + if (isDefined(data.email)) { const customer = await this.createOrFetchUserFromEmail_(data.email) cart.customer = customer cart.customer_id = customer.id @@ -866,14 +863,11 @@ class CartService extends TransactionBaseService { } } - if ( - typeof data.customer_id !== "undefined" || - typeof data.region_id !== "undefined" - ) { + if (isDefined(data.customer_id) || isDefined(data.region_id)) { await this.updateUnitPrices_(cart, data.region_id, data.customer_id) } - if (typeof data.region_id !== "undefined") { + if (isDefined(data.region_id)) { const shippingAddress = typeof data.shipping_address !== "string" ? data.shipping_address @@ -902,7 +896,7 @@ class CartService extends TransactionBaseService { this.featureFlagRouter_.isFeatureEnabled(SalesChannelFeatureFlag.key) ) { if ( - typeof data.sales_channel_id !== "undefined" && + isDefined(data.sales_channel_id) && data.sales_channel_id != cart.sales_channel_id ) { await this.onSalesChannelChange(cart, data.sales_channel_id) @@ -910,7 +904,7 @@ class CartService extends TransactionBaseService { } } - if (typeof data.discounts !== "undefined") { + if (isDefined(data.discounts)) { const previousDiscounts = [...cart.discounts] cart.discounts.length = 0 diff --git a/packages/medusa/src/services/claim.ts b/packages/medusa/src/services/claim.ts index 82340a5c26..b68ac78209 100644 --- a/packages/medusa/src/services/claim.ts +++ b/packages/medusa/src/services/claim.ts @@ -25,7 +25,7 @@ import { LineItemRepository } from "../repositories/line-item" import { MedusaError } from "medusa-core-utils" import { ShippingMethodRepository } from "../repositories/shipping-method" import { TransactionBaseService } from "../interfaces" -import { buildQuery, setMetadata } from "../utils" +import { buildQuery, isDefined, setMetadata } from "../utils" import { FindConfig } from "../types/common" import { CreateClaimInput, UpdateClaimInput } from "../types/claim" @@ -336,7 +336,7 @@ export default class ClaimService extends TransactionBaseService< } let newItems: LineItem[] = [] - if (typeof additional_items !== "undefined") { + if (isDefined(additional_items)) { for (const item of additional_items) { await this.inventoryService_ .withTransaction(transactionManager) diff --git a/packages/medusa/src/services/customer-group.ts b/packages/medusa/src/services/customer-group.ts index 9b46c071da..a094eeb4a7 100644 --- a/packages/medusa/src/services/customer-group.ts +++ b/packages/medusa/src/services/customer-group.ts @@ -9,6 +9,7 @@ import { CustomerGroupUpdate, FilterableCustomerGroupProps, } from "../types/customer-groups" +import { isDefined } from "../utils" import { formatException } from "../utils/exception-formatter" type CustomerGroupConstructorProps = { @@ -173,12 +174,12 @@ class CustomerGroupService extends BaseService { const customerGroup = await this.retrieve(customerGroupId) for (const key in properties) { - if (typeof properties[key] !== "undefined") { + if (isDefined(properties[key])) { customerGroup[key] = properties[key] } } - if (typeof metadata !== "undefined") { + if (isDefined(metadata)) { customerGroup.metadata = this.setMetadata_(customerGroup, metadata) } return await cgRepo.save(customerGroup) diff --git a/packages/medusa/src/services/customer.ts b/packages/medusa/src/services/customer.ts index b2f29a70fd..8487bfc9a0 100644 --- a/packages/medusa/src/services/customer.ts +++ b/packages/medusa/src/services/customer.ts @@ -9,7 +9,7 @@ import { AddressRepository } from "../repositories/address" import { CustomerRepository } from "../repositories/customer" import { AddressCreatePayload, FindConfig, Selector } from "../types/common" import { CreateCustomerInput, UpdateCustomerInput } from "../types/customers" -import { buildQuery, setMetadata } from "../utils" +import { buildQuery, isDefined, setMetadata } from "../utils" import { formatException } from "../utils/exception-formatter" import EventBusService from "./event-bus" @@ -324,7 +324,7 @@ class CustomerService extends TransactionBaseService { if ("billing_address_id" in update || "billing_address" in update) { const address = billing_address_id || billing_address - if (typeof address !== "undefined") { + if (isDefined(address)) { await this.updateBillingAddress_(customer, address) } } @@ -395,7 +395,7 @@ class CustomerService extends TransactionBaseService { address.country_code = address.country_code?.toLowerCase() - if (typeof address?.id !== "undefined") { + if (isDefined(address?.id)) { customer.billing_address_id = address.id } else { if (customer.billing_address_id) { diff --git a/packages/medusa/src/services/fulfillment.ts b/packages/medusa/src/services/fulfillment.ts index 0756f335c7..9a116b595f 100644 --- a/packages/medusa/src/services/fulfillment.ts +++ b/packages/medusa/src/services/fulfillment.ts @@ -13,7 +13,7 @@ import { FulfillmentItemPartition, FulFillmentItemType, } from "../types/fulfillment" -import { buildQuery } from "../utils" +import { buildQuery, isDefined } from "../utils" import FulfillmentProviderService from "./fulfillment-provider" import LineItemService from "./line-item" import TotalsService from "./totals" @@ -336,7 +336,7 @@ class FulfillmentService extends TransactionBaseService { trackingLinkRepo.create(tl) ) - if (typeof no_notification !== "undefined") { + if (isDefined(no_notification)) { fulfillment.no_notification = no_notification } diff --git a/packages/medusa/src/services/gift-card.ts b/packages/medusa/src/services/gift-card.ts index b115b71400..3da6c288e1 100644 --- a/packages/medusa/src/services/gift-card.ts +++ b/packages/medusa/src/services/gift-card.ts @@ -17,7 +17,7 @@ import { CreateGiftCardTransactionInput, UpdateGiftCardInput, } from "../types/gift-card" -import { buildQuery, setMetadata } from "../utils" +import { buildQuery, isDefined, setMetadata } from "../utils" import RegionService from "./region" type InjectedDependencies = { @@ -89,7 +89,7 @@ class GiftCardService extends TransactionBaseService { const giftCardRepo = manager.getCustomRepository(this.giftCardRepository_) let q: string | undefined - if (typeof selector.q !== "undefined") { + if (isDefined(selector.q)) { q = selector.q delete selector.q } @@ -118,7 +118,7 @@ class GiftCardService extends TransactionBaseService { const giftCardRepo = manager.getCustomRepository(this.giftCardRepository_) let q: string | undefined - if (typeof selector.q !== "undefined") { + if (isDefined(selector.q)) { q = selector.q delete selector.q } @@ -255,7 +255,7 @@ class GiftCardService extends TransactionBaseService { giftCard.metadata = setMetadata(giftCard, metadata) } - if (typeof balance !== "undefined") { + if (isDefined(balance)) { if (balance < 0 || giftCard.value < balance) { throw new MedusaError( MedusaError.Types.INVALID_ARGUMENT, diff --git a/packages/medusa/src/services/product-variant.ts b/packages/medusa/src/services/product-variant.ts index 9715c15c45..311e2ce117 100644 --- a/packages/medusa/src/services/product-variant.ts +++ b/packages/medusa/src/services/product-variant.ts @@ -27,6 +27,7 @@ import { ProductVariantPrice, UpdateProductVariantInput, } from "../types/product-variant" +import { isDefined } from "../utils" /** * Provides layer to manipulate product variants. @@ -751,7 +752,7 @@ class ProductVariantService extends BaseService { config: FindConfig ): { query: FindWithRelationsOptions; relations: string[]; q?: string } { let q: string | undefined - if (typeof selector.q !== "undefined") { + if (isDefined(selector.q)) { q = selector.q delete selector.q } diff --git a/packages/medusa/src/services/product.ts b/packages/medusa/src/services/product.ts index 0faa176684..3369949387 100644 --- a/packages/medusa/src/services/product.ts +++ b/packages/medusa/src/services/product.ts @@ -29,7 +29,7 @@ import { ProductOptionInput, UpdateProductInput, } from "../types/product" -import { buildQuery, setMetadata } from "../utils" +import { buildQuery, isDefined, setMetadata } from "../utils" import { formatException } from "../utils/exception-formatter" import EventBusService from "./event-bus" @@ -393,7 +393,7 @@ class ProductService extends TransactionBaseService< if ( this.featureFlagRouter_.isFeatureEnabled(SalesChannelFeatureFlag.key) ) { - if (typeof salesChannels !== "undefined") { + if (isDefined(salesChannels)) { product.sales_channels = [] if (salesChannels?.length) { const salesChannelIds = salesChannels?.map((sc) => sc.id) @@ -464,11 +464,11 @@ class ProductService extends TransactionBaseService< if ( this.featureFlagRouter_.isFeatureEnabled(SalesChannelFeatureFlag.key) ) { - if (typeof update.sales_channels !== "undefined") { + if (isDefined(update.sales_channels)) { relations.push("sales_channels") } } else { - if (typeof update.sales_channels !== "undefined") { + if (isDefined(update.sales_channels)) { throw new MedusaError( MedusaError.Types.INVALID_DATA, "the property sales_channels should no appears as part of the payload" @@ -513,7 +513,7 @@ class ProductService extends TransactionBaseService< if ( this.featureFlagRouter_.isFeatureEnabled(SalesChannelFeatureFlag.key) ) { - if (typeof salesChannels !== "undefined") { + if (isDefined(salesChannels)) { product.sales_channels = [] if (salesChannels?.length) { const salesChannelIds = salesChannels?.map((sc) => sc.id) diff --git a/packages/medusa/src/services/return.js b/packages/medusa/src/services/return.js index 81696b2472..5de7d227a8 100644 --- a/packages/medusa/src/services/return.js +++ b/packages/medusa/src/services/return.js @@ -1,5 +1,6 @@ import { MedusaError } from "medusa-core-utils" import { BaseService } from "medusa-interfaces" +import { isDefined } from "../utils" /** * Handles Returns @@ -357,7 +358,7 @@ class ReturnService extends BaseService { ) 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 // refundable const refundable = order.refundable_amount diff --git a/packages/medusa/src/services/shipping-option.ts b/packages/medusa/src/services/shipping-option.ts index 358d3e65a4..0eef3b2ce5 100644 --- a/packages/medusa/src/services/shipping-option.ts +++ b/packages/medusa/src/services/shipping-option.ts @@ -19,7 +19,7 @@ import { UpdateShippingOptionInput, CreateShippingOptionInput, } from "../types/shipping-options" -import { buildQuery, setMetadata } from "../utils" +import { buildQuery, isDefined, setMetadata } from "../utils" import FulfillmentProviderService from "./fulfillment-provider" import RegionService from "./region" @@ -262,7 +262,7 @@ class ShippingOptionService extends TransactionBaseService { if (next === "cart") { @@ -140,7 +141,7 @@ class SwapService extends BaseService { cartRelations = cartRels let foundCartId = false - if (typeof select !== "undefined") { + if (isDefined(select)) { const [swapSelects, cartSels] = select.reduce( (acc, next) => { if (next.startsWith("cart.")) { diff --git a/packages/medusa/src/services/tax-rate.ts b/packages/medusa/src/services/tax-rate.ts index 5b7829be22..c0aed1d12d 100644 --- a/packages/medusa/src/services/tax-rate.ts +++ b/packages/medusa/src/services/tax-rate.ts @@ -16,6 +16,7 @@ import { TaxRateListByConfig, UpdateTaxRateInput, } from "../types/tax-rate" +import { isDefined } from "../utils" class TaxRateService extends BaseService { private manager_: EntityManager @@ -122,7 +123,7 @@ class TaxRateService extends BaseService { const taxRate = await this.retrieve(id) for (const [k, v] of Object.entries(data)) { - if (typeof v !== "undefined") { + if (isDefined(v)) { taxRate[k] = v } } diff --git a/packages/medusa/src/services/totals.ts b/packages/medusa/src/services/totals.ts index b21d4fe702..8addac9e7a 100644 --- a/packages/medusa/src/services/totals.ts +++ b/packages/medusa/src/services/totals.ts @@ -23,6 +23,7 @@ import { } from "../types/totals" import TaxProviderService from "./tax-provider" import { EntityManager } from "typeorm" +import { isDefined } from "../utils" type ShippingMethodTotals = { price: number @@ -315,8 +316,8 @@ class TotalsService extends TransactionBaseService { let taxLines: (ShippingMethodTaxLine | LineItemTaxLine)[] if (isOrder(cartOrOrder)) { - const taxLinesJoined = cartOrOrder.items.every( - (i) => typeof i.tax_lines !== "undefined" + const taxLinesJoined = cartOrOrder.items.every((i) => + isDefined(i.tax_lines) ) if (!taxLinesJoined) { throw new MedusaError( diff --git a/packages/medusa/src/strategies/price-selection.ts b/packages/medusa/src/strategies/price-selection.ts index d128169f79..68e635928b 100644 --- a/packages/medusa/src/strategies/price-selection.ts +++ b/packages/medusa/src/strategies/price-selection.ts @@ -7,6 +7,7 @@ import { } from "../interfaces/price-selection-strategy" import { MoneyAmountRepository } from "../repositories/money-amount" import { EntityManager } from "typeorm" +import { isDefined } from "../utils" class PriceSelectionStrategy extends AbstractPriceSelectionStrategy { private moneyAmountRepository_: typeof MoneyAmountRepository @@ -103,8 +104,7 @@ class PriceSelectionStrategy extends AbstractPriceSelectionStrategy { } const isValidQuantity = (price, quantity): boolean => - (typeof quantity !== "undefined" && - isValidPriceWithQuantity(price, quantity)) || + (isDefined(quantity) && isValidPriceWithQuantity(price, quantity)) || (typeof quantity === "undefined" && isValidPriceWithoutQuantity(price)) const isValidPriceWithoutQuantity = (price): boolean => diff --git a/packages/medusa/src/utils/get-query-config.ts b/packages/medusa/src/utils/get-query-config.ts index 841a4981b0..8bc8e6b02c 100644 --- a/packages/medusa/src/utils/get-query-config.ts +++ b/packages/medusa/src/utils/get-query-config.ts @@ -2,6 +2,7 @@ import { pick } from "lodash" import { FindConfig, QueryConfig, RequestQueryFields } from "../types/common" import { MedusaError } from "medusa-core-utils/dist" import { BaseEntity } from "../interfaces/models/base-entity" +import { isDefined } from "." export function pickByConfig( obj: TModel | TModel[], @@ -26,14 +27,14 @@ export function getRetrieveConfig( expand?: string[] ): FindConfig { let includeFields: (keyof TModel)[] = [] - if (typeof fields !== "undefined") { + if (isDefined(fields)) { includeFields = Array.from(new Set([...fields, "id"])).map((field) => typeof field === "string" ? field.trim() : field ) as (keyof TModel)[] } let expandFields: string[] = [] - if (typeof expand !== "undefined") { + if (isDefined(expand)) { expandFields = expand.map((expandRelation) => expandRelation.trim()) } @@ -53,7 +54,7 @@ export function getListConfig( order?: { [k: symbol]: "DESC" | "ASC" } ): FindConfig { let includeFields: (keyof TModel)[] = [] - if (typeof fields !== "undefined") { + if (isDefined(fields)) { const fieldSet = new Set(fields) // Ensure created_at is included, since we are sorting on this fieldSet.add("created_at") @@ -62,7 +63,7 @@ export function getListConfig( } let expandFields: string[] = [] - if (typeof expand !== "undefined") { + if (isDefined(expand)) { expandFields = expand } @@ -96,7 +97,7 @@ export function prepareListQuery< } let orderBy: { [k: symbol]: "DESC" | "ASC" } | undefined - if (typeof order !== "undefined") { + if (isDefined(order)) { let orderField = order if (order.startsWith("-")) { const [, field] = order.split("-") diff --git a/packages/medusa/src/utils/index.ts b/packages/medusa/src/utils/index.ts index 6b1988de67..d56c80bac0 100644 --- a/packages/medusa/src/utils/index.ts +++ b/packages/medusa/src/utils/index.ts @@ -3,3 +3,4 @@ export * from "./set-metadata" export * from "./validate-id" export * from "./generate-entity-id" export * from "./remove-undefined-properties" +export * from "./is-defined" diff --git a/packages/medusa/src/utils/is-defined.ts b/packages/medusa/src/utils/is-defined.ts new file mode 100644 index 0000000000..2d4da48450 --- /dev/null +++ b/packages/medusa/src/utils/is-defined.ts @@ -0,0 +1,3 @@ +export function isDefined(val: T): val is (T extends undefined ? never : T) { + return typeof val !== "undefined" +} diff --git a/packages/medusa/src/utils/remove-undefined-properties.ts b/packages/medusa/src/utils/remove-undefined-properties.ts index 0898238880..010f9c3588 100644 --- a/packages/medusa/src/utils/remove-undefined-properties.ts +++ b/packages/medusa/src/utils/remove-undefined-properties.ts @@ -1,3 +1,5 @@ +import { isDefined } from "./is-defined"; + export function removeUndefinedProperties(inputObj: T): T { const removeProperties = (obj: T) => { const res = {} as T @@ -17,13 +19,13 @@ export function removeUndefinedProperties(inputObj: T): T { } function removeUndefinedDeeply(input: unknown): any { - if (typeof input !== "undefined") { + if (isDefined(input)) { if (input === null || input === "null") { return null } else if (Array.isArray(input)) { return input.map((item) => { return removeUndefinedDeeply(item) - }).filter(v => typeof v !== "undefined") + }).filter(v => isDefined(v)) } else if (Object.prototype.toString.call(input) === '[object Date]') { return input } else if (typeof input === "object") {