chore(utils): Move generic utils from region module to utils (#6466)

Moves some generic utilities from the region module to the top-level utils package
This commit is contained in:
Stevche Radevski
2024-02-22 09:06:46 +01:00
committed by GitHub
parent 5a15e039ec
commit add861d205
6 changed files with 68 additions and 24 deletions

View File

@@ -23,11 +23,13 @@ import {
MedusaError,
ModulesSdkUtils,
promiseAll,
DefaultsUtils,
removeUndefined,
getDuplicates,
} from "@medusajs/utils"
import { Country, Currency, Region } from "@models"
import { DefaultsUtils } from "@medusajs/utils"
import { CreateCountryDTO, CreateCurrencyDTO } from "@types"
import { entityNameToLinkableKeysMap, joinerConfig } from "../joiner-config"
@@ -304,7 +306,7 @@ export default class RegionModuleService<
if (uniqueCountries.length !== countries.length) {
throw new MedusaError(
MedusaError.Types.INVALID_DATA,
`Countries with codes: "${getDuplicateEntries(countries).join(
`Countries with codes: "${getDuplicates(countries).join(
", "
)}" are already assigned to a region`
)
@@ -413,25 +415,3 @@ export default class RegionModuleService<
}
}
}
// microORM complains if undefined fields are present in the passed data object
const removeUndefined = <T extends Record<string, any>>(obj: T): T => {
return Object.fromEntries(
Object.entries(obj).filter(([_, v]) => v !== undefined)
) as T
}
const getDuplicateEntries = (collection: string[]): string[] => {
const uniqueElements = new Set()
const duplicates: string[] = []
collection.forEach((item) => {
if (uniqueElements.has(item)) {
duplicates.push(item)
} else {
uniqueElements.add(item)
}
})
return duplicates
}

View File

@@ -0,0 +1,20 @@
import { getDuplicates } from "../get-duplicates"
describe("getDuplicates", function () {
it("should return an empty array if there are no duplicates", function () {
const output = getDuplicates(["foo", "bar", "baz"])
expect(output).toHaveLength(0)
})
it("should return a singular duplicate", function () {
const output = getDuplicates(["foo", "bar", "baz", "baz", "baz"])
expect(output).toHaveLength(1)
expect(output[0]).toEqual("baz")
})
it("should return all duplicates in the array", function () {
const output = getDuplicates(["foo", "bar", "bar", "baz", "baz", "baz"])
expect(output).toHaveLength(2)
expect(output).toEqual(expect.arrayContaining(["baz", "bar"]))
})
})

View File

@@ -0,0 +1,22 @@
import { removeUndefined } from "../remove-undefined"
describe("removeUndefined", function () {
it("should remove all undefined fields from an object", function () {
const withUndefined = {
foo: undefined,
bar: "baz",
foo2: null,
}
expect(withUndefined.hasOwnProperty("foo")).toBe(true)
const output = removeUndefined(withUndefined)
expect(output.hasOwnProperty("foo")).toBe(false)
expect(output.hasOwnProperty("bar")).toBe(true)
expect(output.hasOwnProperty("foo2")).toBe(true)
})
it("should return an empty object as-is", function () {
const output = removeUndefined({})
expect(output).toEqual({})
})
})

View File

@@ -0,0 +1,16 @@
// This function is intentionally not generic, as we will likely need a comparator function in that case, which will make it more complex than necessary
// Revisit if there is such use-case in the future
export const getDuplicates = (collection: string[]): string[] => {
const uniqueElements = new Set<string>()
const duplicates = new Set<string>()
collection.forEach((item) => {
if (uniqueElements.has(item)) {
duplicates.add(item)
} else {
uniqueElements.add(item)
}
})
return Array.from(duplicates)
}

View File

@@ -47,3 +47,5 @@ export * from "./to-pascal-case"
export * from "./transaction"
export * from "./upper-case-first"
export * from "./wrap-handler"
export * from "./remove-undefined"
export * from "./get-duplicates"

View File

@@ -0,0 +1,4 @@
// useful in cases where presence of undefined is not desired (eg. in microORM operations)
export const removeUndefined = <T extends Record<string, any>>(obj: T): T => {
return JSON.parse(JSON.stringify(obj)) as T
}