fix(utils): define link alias + pluralize (#8070)
What: * Fix alias of models that have "compound names": eg "related_product" * `deleteCascade` option * Package to pluralize english words correctly
This commit is contained in:
committed by
GitHub
parent
256912f392
commit
f460348280
@@ -1,8 +1,9 @@
|
||||
import { medusaIntegrationTestRunner } from "medusa-test-utils"
|
||||
|
||||
import CurrencyModule from "@medusajs/currency"
|
||||
import { MedusaModule } from "@medusajs/modules-sdk"
|
||||
import RegionModule from "@medusajs/region"
|
||||
import { defineLink } from "@medusajs/utils"
|
||||
import { MedusaModule } from "@medusajs/modules-sdk"
|
||||
|
||||
jest.setTimeout(50000)
|
||||
|
||||
@@ -46,6 +47,7 @@ medusaIntegrationTestRunner({
|
||||
args: {
|
||||
methodSuffix: "Currencies",
|
||||
},
|
||||
deleteCascade: false,
|
||||
},
|
||||
{
|
||||
serviceName: "region",
|
||||
@@ -55,6 +57,94 @@ medusaIntegrationTestRunner({
|
||||
args: {
|
||||
methodSuffix: "Regions",
|
||||
},
|
||||
deleteCascade: false,
|
||||
},
|
||||
],
|
||||
extends: [
|
||||
{
|
||||
serviceName: "currency",
|
||||
fieldAlias: {
|
||||
region: "region_link.region",
|
||||
},
|
||||
relationship: {
|
||||
serviceName: "currencyCurrencyRegionRegionLink",
|
||||
primaryKey: "currency_code",
|
||||
foreignKey: "code",
|
||||
alias: "region_link",
|
||||
isList: false,
|
||||
},
|
||||
},
|
||||
{
|
||||
serviceName: "region",
|
||||
fieldAlias: {
|
||||
currency: "currency_link.currency",
|
||||
},
|
||||
relationship: {
|
||||
serviceName: "currencyCurrencyRegionRegionLink",
|
||||
primaryKey: "region_id",
|
||||
foreignKey: "id",
|
||||
alias: "currency_link",
|
||||
isList: false,
|
||||
},
|
||||
},
|
||||
],
|
||||
})
|
||||
})
|
||||
|
||||
it("should flag deleteCascade in the link definition", async () => {
|
||||
const currencyLinks = CurrencyModule.linkable
|
||||
const regionLinks = RegionModule.linkable
|
||||
|
||||
const link = defineLink(
|
||||
{
|
||||
linkable: currencyLinks.currency,
|
||||
deleteCascade: true,
|
||||
},
|
||||
regionLinks.region
|
||||
)
|
||||
|
||||
const linkDefinition = MedusaModule.getCustomLinks()
|
||||
.map((linkDefinition: any) => {
|
||||
const definition = linkDefinition(
|
||||
MedusaModule.getAllJoinerConfigs()
|
||||
)
|
||||
return definition.serviceName === link.serviceName && definition
|
||||
})
|
||||
.filter(Boolean)[0]
|
||||
|
||||
expect(link.serviceName).toEqual("currencyCurrencyRegionRegionLink")
|
||||
expect(linkDefinition).toEqual({
|
||||
serviceName: "currencyCurrencyRegionRegionLink",
|
||||
isLink: true,
|
||||
alias: [
|
||||
{
|
||||
name: ["currency_region"],
|
||||
args: {
|
||||
entity: "LinkCurrencyCurrencyRegionRegion",
|
||||
},
|
||||
},
|
||||
],
|
||||
primaryKeys: ["id", "currency_code", "region_id"],
|
||||
relationships: [
|
||||
{
|
||||
serviceName: "currency",
|
||||
primaryKey: "code",
|
||||
foreignKey: "currency_code",
|
||||
alias: "currency",
|
||||
args: {
|
||||
methodSuffix: "Currencies",
|
||||
},
|
||||
deleteCascade: true,
|
||||
},
|
||||
{
|
||||
serviceName: "region",
|
||||
primaryKey: "id",
|
||||
foreignKey: "region_id",
|
||||
alias: "region",
|
||||
args: {
|
||||
methodSuffix: "Regions",
|
||||
},
|
||||
deleteCascade: false,
|
||||
},
|
||||
],
|
||||
extends: [
|
||||
@@ -128,6 +218,7 @@ medusaIntegrationTestRunner({
|
||||
args: {
|
||||
methodSuffix: "Currencies",
|
||||
},
|
||||
deleteCascade: false,
|
||||
},
|
||||
{
|
||||
serviceName: "region",
|
||||
@@ -137,6 +228,7 @@ medusaIntegrationTestRunner({
|
||||
args: {
|
||||
methodSuffix: "Regions",
|
||||
},
|
||||
deleteCascade: false,
|
||||
},
|
||||
],
|
||||
extends: [
|
||||
|
||||
@@ -353,6 +353,18 @@ export type Pluralize<Singular extends string> = Singular extends `${infer R}ey`
|
||||
| `${infer R}z`
|
||||
| `${infer R}o`
|
||||
? `${Singular}es`
|
||||
: Singular extends `${infer R}fe`
|
||||
? `${R}ves`
|
||||
: Singular extends `${infer R}ex` | `${infer R}ix`
|
||||
? `${R}ices`
|
||||
: Singular extends `${infer R}eau`
|
||||
? `${R}eaux`
|
||||
: Singular extends `${infer R}ieu`
|
||||
? `${R}ieux`
|
||||
: Singular extends `${infer R}sis`
|
||||
? `${R}ses`
|
||||
: Singular extends `${infer R}is`
|
||||
? `${R}ises`
|
||||
: `${Singular}s`
|
||||
|
||||
export type SnakeCase<S extends string> =
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
"dotenv": "^16.4.5",
|
||||
"jsonwebtoken": "^9.0.2",
|
||||
"knex": "2.4.2",
|
||||
"pluralize": "^8.0.0",
|
||||
"ulid": "^2.3.0"
|
||||
},
|
||||
"scripts": {
|
||||
|
||||
@@ -1,27 +1,10 @@
|
||||
import pluralizeEN from "pluralize"
|
||||
|
||||
/**
|
||||
* Some library provide pluralize function with language specific rules.
|
||||
* This is a simple implementation of pluralize function.
|
||||
* Function to pluralize English words.
|
||||
* @param word
|
||||
*/
|
||||
export function pluralize(word: string): string {
|
||||
// Add basic rules for forming plurals
|
||||
if (
|
||||
//word.endsWith("s") ||
|
||||
word.endsWith("sh") ||
|
||||
word.endsWith("ss") ||
|
||||
word.endsWith("ch") ||
|
||||
word.endsWith("x") ||
|
||||
word.endsWith("o") ||
|
||||
word.endsWith("z")
|
||||
) {
|
||||
return word + "es"
|
||||
} else if (word.endsWith("y") && !"aeiou".includes(word[word.length - 2])) {
|
||||
return word.slice(0, -1) + "ies"
|
||||
} else if (word.endsWith("es")) {
|
||||
return word
|
||||
} else if (word.endsWith("fe")) {
|
||||
return word.slice(0, -2) + "ves"
|
||||
} else {
|
||||
return word + "s"
|
||||
}
|
||||
// TODO: Implement language specific pluralize function
|
||||
return pluralizeEN(word)
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { LinkModulesExtraFields, ModuleJoinerConfig } from "@medusajs/types"
|
||||
import { isObject, pluralize, toPascalCase } from "../common"
|
||||
import { camelToSnakeCase, isObject, pluralize, toPascalCase } from "../common"
|
||||
import { composeLinkName } from "../link"
|
||||
|
||||
export const DefineLinkSymbol = Symbol.for("DefineLink")
|
||||
@@ -25,6 +25,7 @@ type CombinedSource = Record<any, any> & InputToJson
|
||||
type InputOptions = {
|
||||
linkable: CombinedSource | InputSource
|
||||
isList?: boolean
|
||||
deleteCascade?: boolean
|
||||
}
|
||||
|
||||
type ExtraOptions = {
|
||||
@@ -44,6 +45,7 @@ type ModuleLinkableKeyConfig = {
|
||||
module: string
|
||||
key: string
|
||||
isList?: boolean
|
||||
deleteCascade?: boolean
|
||||
primaryKey: string
|
||||
alias: string
|
||||
shortcuts?: {
|
||||
@@ -52,15 +54,15 @@ type ModuleLinkableKeyConfig = {
|
||||
}
|
||||
|
||||
function isInputOptions(input: any): input is InputOptions {
|
||||
return isObject(input) && "linkable" in input
|
||||
return isObject(input) && input?.["linkable"]
|
||||
}
|
||||
|
||||
function isInputSource(input: any): input is InputSource {
|
||||
return (isObject(input) && "serviceName" in input) || "toJSON" in input
|
||||
return (isObject(input) && input?.["serviceName"]) || input?.["toJSON"]
|
||||
}
|
||||
|
||||
function isToJSON(input: any): input is InputToJson {
|
||||
return isObject(input) && "toJSON" in input
|
||||
return isObject(input) && input?.["toJSON"]
|
||||
}
|
||||
|
||||
export function defineLink(
|
||||
@@ -79,6 +81,7 @@ export function defineLink(
|
||||
alias: source.field,
|
||||
primaryKey: source.primaryKey,
|
||||
isList: false,
|
||||
deleteCascade: false,
|
||||
module: source.serviceName,
|
||||
}
|
||||
} else if (isInputOptions(leftService)) {
|
||||
@@ -91,6 +94,7 @@ export function defineLink(
|
||||
alias: source.field,
|
||||
primaryKey: source.primaryKey,
|
||||
isList: leftService.isList ?? false,
|
||||
deleteCascade: leftService.deleteCascade ?? false,
|
||||
module: source.serviceName,
|
||||
}
|
||||
} else {
|
||||
@@ -102,9 +106,10 @@ export function defineLink(
|
||||
|
||||
serviceBObj = {
|
||||
key: source.linkable,
|
||||
alias: source.field,
|
||||
alias: camelToSnakeCase(source.field),
|
||||
primaryKey: source.primaryKey,
|
||||
isList: false,
|
||||
deleteCascade: false,
|
||||
module: source.serviceName,
|
||||
}
|
||||
} else if (isInputOptions(rightService)) {
|
||||
@@ -114,9 +119,10 @@ export function defineLink(
|
||||
|
||||
serviceBObj = {
|
||||
key: source.linkable,
|
||||
alias: source.field,
|
||||
alias: camelToSnakeCase(source.field),
|
||||
primaryKey: source.primaryKey,
|
||||
isList: rightService.isList ?? false,
|
||||
deleteCascade: rightService.deleteCascade ?? false,
|
||||
module: source.serviceName,
|
||||
}
|
||||
} else {
|
||||
@@ -281,6 +287,7 @@ export function defineLink(
|
||||
args: {
|
||||
methodSuffix: serviceAMethodSuffix,
|
||||
},
|
||||
deleteCascade: serviceAObj.deleteCascade,
|
||||
},
|
||||
{
|
||||
serviceName: serviceBObj.module,
|
||||
@@ -290,6 +297,7 @@ export function defineLink(
|
||||
args: {
|
||||
methodSuffix: serviceBMethodSuffix,
|
||||
},
|
||||
deleteCascade: serviceBObj.deleteCascade,
|
||||
},
|
||||
],
|
||||
extends: [
|
||||
@@ -297,13 +305,13 @@ export function defineLink(
|
||||
serviceName: serviceAObj.module,
|
||||
fieldAlias: {
|
||||
[serviceBObj.isList ? pluralize(aliasB) : aliasB]:
|
||||
aliasB + "_link." + aliasB, //plural aliasA
|
||||
aliasB + "_link." + aliasB,
|
||||
},
|
||||
relationship: {
|
||||
serviceName: output.serviceName,
|
||||
primaryKey: serviceAObj.key,
|
||||
foreignKey: serviceAPrimaryKey,
|
||||
alias: aliasB + "_link", // plural alias
|
||||
alias: aliasB + "_link",
|
||||
isList: serviceBObj.isList,
|
||||
},
|
||||
},
|
||||
@@ -317,7 +325,7 @@ export function defineLink(
|
||||
serviceName: output.serviceName,
|
||||
primaryKey: serviceBObj.key,
|
||||
foreignKey: serviceBPrimaryKey,
|
||||
alias: aliasA + "_link", // plural alias
|
||||
alias: aliasA + "_link",
|
||||
isList: serviceAObj.isList,
|
||||
},
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user