chore(): Reorganize modules (#7210)
**What** Move all modules to the modules directory
This commit is contained in:
committed by
GitHub
parent
7a351eef09
commit
4eae25e1ef
@@ -0,0 +1,9 @@
|
||||
import { lowerCaseFirst, toPascalCase } from "@medusajs/utils"
|
||||
|
||||
export const composeLinkName = (...args) => {
|
||||
return lowerCaseFirst(toPascalCase(composeTableName(...args.concat("link"))))
|
||||
}
|
||||
|
||||
export const composeTableName = (...args) => {
|
||||
return args.map((name) => name.replace(/(_id|Service)$/gi, "")).join("_")
|
||||
}
|
||||
117
packages/modules/link-modules/src/utils/generate-entity.ts
Normal file
117
packages/modules/link-modules/src/utils/generate-entity.ts
Normal file
@@ -0,0 +1,117 @@
|
||||
import { JoinerRelationship, ModuleJoinerConfig } from "@medusajs/types"
|
||||
import {
|
||||
SoftDeletableFilterKey,
|
||||
mikroOrmSoftDeletableFilterOptions,
|
||||
simpleHash,
|
||||
} from "@medusajs/utils"
|
||||
|
||||
import { EntitySchema } from "@mikro-orm/core"
|
||||
import { composeTableName } from "./compose-link-name"
|
||||
|
||||
function getClass(...properties) {
|
||||
return class LinkModel {
|
||||
constructor(...values) {
|
||||
properties.forEach((name, idx) => {
|
||||
this[name] = values[idx]
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function generateEntity(
|
||||
joinerConfig: ModuleJoinerConfig,
|
||||
primary: JoinerRelationship,
|
||||
foreign: JoinerRelationship
|
||||
) {
|
||||
const fieldNames = primary.foreignKey.split(",").concat(foreign.foreignKey)
|
||||
|
||||
const tableName =
|
||||
joinerConfig.databaseConfig?.tableName ??
|
||||
composeTableName(
|
||||
primary.serviceName,
|
||||
primary.foreignKey,
|
||||
foreign.serviceName,
|
||||
foreign.foreignKey
|
||||
)
|
||||
|
||||
const fields = fieldNames.reduce((acc, curr) => {
|
||||
acc[curr] = {
|
||||
type: "string",
|
||||
nullable: false,
|
||||
primary: true,
|
||||
}
|
||||
return acc
|
||||
}, {})
|
||||
|
||||
const extraFields = joinerConfig.databaseConfig?.extraFields ?? {}
|
||||
|
||||
for (const column in extraFields) {
|
||||
fieldNames.push(column)
|
||||
|
||||
fields[column] = {
|
||||
type: extraFields[column].type,
|
||||
nullable: !!extraFields[column].nullable,
|
||||
defaultRaw: extraFields[column].defaultValue,
|
||||
...(extraFields[column].options ?? {}),
|
||||
}
|
||||
}
|
||||
|
||||
const hashTableName = simpleHash(tableName)
|
||||
|
||||
return new EntitySchema({
|
||||
class: getClass(
|
||||
...fieldNames.concat("created_at", "updated_at", "deleted_at")
|
||||
) as any,
|
||||
tableName,
|
||||
properties: {
|
||||
id: {
|
||||
type: "string",
|
||||
nullable: false,
|
||||
},
|
||||
...fields,
|
||||
created_at: {
|
||||
type: "Date",
|
||||
nullable: false,
|
||||
defaultRaw: "CURRENT_TIMESTAMP",
|
||||
},
|
||||
updated_at: {
|
||||
type: "Date",
|
||||
nullable: false,
|
||||
defaultRaw: "CURRENT_TIMESTAMP",
|
||||
},
|
||||
deleted_at: { type: "Date", nullable: true },
|
||||
},
|
||||
filters: {
|
||||
[SoftDeletableFilterKey]: mikroOrmSoftDeletableFilterOptions,
|
||||
},
|
||||
hooks: {
|
||||
beforeUpdate: [
|
||||
(args) => {
|
||||
args.entity.updated_at = new Date()
|
||||
},
|
||||
],
|
||||
},
|
||||
indexes: [
|
||||
{
|
||||
properties: ["id"],
|
||||
name: "IDX_id_" + hashTableName,
|
||||
},
|
||||
{
|
||||
properties: primary.foreignKey.split(","),
|
||||
name:
|
||||
"IDX_" +
|
||||
primary.foreignKey.split(",").join("_") +
|
||||
"_" +
|
||||
hashTableName,
|
||||
},
|
||||
{
|
||||
properties: foreign.foreignKey,
|
||||
name: "IDX_" + foreign.foreignKey + "_" + hashTableName,
|
||||
},
|
||||
{
|
||||
properties: ["deleted_at"],
|
||||
name: "IDX_deleted_at_" + hashTableName,
|
||||
},
|
||||
],
|
||||
})
|
||||
}
|
||||
152
packages/modules/link-modules/src/utils/generate-schema.ts
Normal file
152
packages/modules/link-modules/src/utils/generate-schema.ts
Normal file
@@ -0,0 +1,152 @@
|
||||
import { MedusaModule } from "@medusajs/modules-sdk"
|
||||
import { ModuleJoinerConfig, ModuleJoinerRelationship } from "@medusajs/types"
|
||||
import { camelToSnakeCase, lowerCaseFirst, toPascalCase } from "@medusajs/utils"
|
||||
import { composeTableName } from "./compose-link-name"
|
||||
|
||||
export function generateGraphQLSchema(
|
||||
joinerConfig: ModuleJoinerConfig,
|
||||
primary: ModuleJoinerRelationship,
|
||||
foreign: ModuleJoinerRelationship,
|
||||
{ logger }: { logger } = { logger: console }
|
||||
) {
|
||||
let fieldNames!: string[]
|
||||
let entityName!: string
|
||||
|
||||
if (!joinerConfig.isReadOnlyLink) {
|
||||
fieldNames = primary.foreignKey.split(",").concat(foreign.foreignKey)
|
||||
|
||||
entityName = toPascalCase(
|
||||
"Link_" +
|
||||
(joinerConfig.databaseConfig?.tableName ??
|
||||
composeTableName(
|
||||
primary.serviceName,
|
||||
primary.foreignKey,
|
||||
foreign.serviceName,
|
||||
foreign.foreignKey
|
||||
))
|
||||
)
|
||||
}
|
||||
|
||||
let typeDef = ""
|
||||
|
||||
for (const extend of joinerConfig.extends ?? []) {
|
||||
const extendedModule = MedusaModule.getModuleInstance(extend.serviceName)
|
||||
if (!extendedModule && !extend.relationship.isInternalService) {
|
||||
throw new Error(
|
||||
`Module ${extend.serviceName} not found. Please verify that the module is configured and installed, also the module must be loaded before the link modules.`
|
||||
)
|
||||
}
|
||||
|
||||
const extJoinerConfig = MedusaModule.getJoinerConfig(
|
||||
extend.relationship.serviceName
|
||||
)
|
||||
let extendedEntityName =
|
||||
extJoinerConfig?.linkableKeys?.[extend.relationship.foreignKey]!
|
||||
|
||||
if (!extendedEntityName && (!primary || !foreign)) {
|
||||
logger.warn(
|
||||
`Link modules schema: No linkable key found for ${extend.relationship.foreignKey} on module ${extend.relationship.serviceName}.`
|
||||
)
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
const fieldName = camelToSnakeCase(
|
||||
lowerCaseFirst(extend.relationship.alias)
|
||||
)
|
||||
|
||||
let type = extend.relationship.isList ? `[${entityName}]` : entityName
|
||||
if (extJoinerConfig?.isReadOnlyLink) {
|
||||
type = extend.relationship.isList
|
||||
? `[${extendedEntityName}]`
|
||||
: extendedEntityName
|
||||
}
|
||||
|
||||
typeDef += `
|
||||
extend type ${extend.serviceName} {
|
||||
${fieldName}: ${type}
|
||||
}
|
||||
`
|
||||
}
|
||||
|
||||
if (joinerConfig.isReadOnlyLink) {
|
||||
return typeDef
|
||||
}
|
||||
|
||||
// Pivot table fields
|
||||
const fields = fieldNames.reduce((acc, curr) => {
|
||||
acc[curr] = {
|
||||
type: "String",
|
||||
nullable: false,
|
||||
}
|
||||
return acc
|
||||
}, {})
|
||||
|
||||
const extraFields = joinerConfig.databaseConfig?.extraFields ?? {}
|
||||
|
||||
for (const column in extraFields) {
|
||||
fields[column] = {
|
||||
type: getGraphQLType(extraFields[column].type),
|
||||
nullable: !!extraFields[column].nullable,
|
||||
}
|
||||
}
|
||||
|
||||
// Link table relationships
|
||||
const primaryField = `${camelToSnakeCase(primary.alias)}: ${toPascalCase(
|
||||
composeTableName(primary.serviceName)
|
||||
)}`
|
||||
|
||||
const foreignField = `${camelToSnakeCase(foreign.alias)}: ${toPascalCase(
|
||||
composeTableName(foreign.serviceName)
|
||||
)}`
|
||||
|
||||
typeDef += `
|
||||
type ${entityName} {
|
||||
${(Object.entries(fields) as any)
|
||||
.map(
|
||||
([field, { type, nullable }]) =>
|
||||
`${field}: ${nullable ? type : `${type}!`}`
|
||||
)
|
||||
.join("\n ")}
|
||||
|
||||
${primaryField}
|
||||
${foreignField}
|
||||
|
||||
createdAt: String!
|
||||
updatedAt: String!
|
||||
deletedAt: String
|
||||
}
|
||||
`
|
||||
|
||||
return typeDef
|
||||
}
|
||||
|
||||
function getGraphQLType(type) {
|
||||
const typeDef = {
|
||||
numeric: "Float",
|
||||
integer: "Int",
|
||||
smallint: "Int",
|
||||
tinyint: "Int",
|
||||
mediumint: "Int",
|
||||
float: "Float",
|
||||
double: "Float",
|
||||
boolean: "Boolean",
|
||||
decimal: "Float",
|
||||
string: "String",
|
||||
uuid: "ID",
|
||||
text: "String",
|
||||
date: "Date",
|
||||
time: "Time",
|
||||
datetime: "DateTime",
|
||||
bigint: "BigInt",
|
||||
blob: "Blob",
|
||||
uint8array: "[Int]",
|
||||
array: "[String]",
|
||||
enumArray: "[String]",
|
||||
enum: "String",
|
||||
json: "JSON",
|
||||
jsonb: "JSON",
|
||||
}
|
||||
|
||||
return typeDef[type] ?? "String"
|
||||
}
|
||||
13
packages/modules/link-modules/src/utils/index.ts
Normal file
13
packages/modules/link-modules/src/utils/index.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
import { MODULE_RESOURCE_TYPE } from "@medusajs/types"
|
||||
|
||||
export * from "./compose-link-name"
|
||||
export * from "./generate-entity"
|
||||
export * from "./generate-schema"
|
||||
|
||||
export function shouldForceTransaction(target: any): boolean {
|
||||
return target.moduleDeclaration?.resources === MODULE_RESOURCE_TYPE.ISOLATED
|
||||
}
|
||||
|
||||
export function doNotForceTransaction(): boolean {
|
||||
return false
|
||||
}
|
||||
Reference in New Issue
Block a user