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:
@@ -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
|
||||
}
|
||||
|
||||
20
packages/utils/src/common/__tests__/get-duplicates.spec.ts
Normal file
20
packages/utils/src/common/__tests__/get-duplicates.spec.ts
Normal 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"]))
|
||||
})
|
||||
})
|
||||
22
packages/utils/src/common/__tests__/remove-undefined.spec.ts
Normal file
22
packages/utils/src/common/__tests__/remove-undefined.spec.ts
Normal 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({})
|
||||
})
|
||||
})
|
||||
16
packages/utils/src/common/get-duplicates.ts
Normal file
16
packages/utils/src/common/get-duplicates.ts
Normal 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)
|
||||
}
|
||||
@@ -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"
|
||||
|
||||
4
packages/utils/src/common/remove-undefined.ts
Normal file
4
packages/utils/src/common/remove-undefined.ts
Normal 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
|
||||
}
|
||||
Reference in New Issue
Block a user