diff --git a/.changeset/quiet-spiders-join.md b/.changeset/quiet-spiders-join.md new file mode 100644 index 0000000000..413924742e --- /dev/null +++ b/.changeset/quiet-spiders-join.md @@ -0,0 +1,6 @@ +--- +"@medusajs/openapi-typescript-codegen": minor +"@medusajs/client-types": minor +--- + +feat(codegen,types): SetRelation on expanded types diff --git a/packages/generated/client-types/src/index.ts b/packages/generated/client-types/src/index.ts index 0cc1837b10..56e3ef1d4b 100644 --- a/packages/generated/client-types/src/index.ts +++ b/packages/generated/client-types/src/index.ts @@ -1 +1,7 @@ export * from "./lib" +export { + Merge, + SetNonNullable, + SetRelation, + SetRequired, +} from "./lib/core/ModelUtils" diff --git a/packages/oas/openapi-typescript-codegen/src/openApi/v3/interfaces/Extensions/WithDefaultRelationsExtension.d.ts b/packages/oas/openapi-typescript-codegen/src/openApi/v3/interfaces/Extensions/WithDefaultRelationsExtension.d.ts index 2a794852ea..9427a7ddc2 100644 --- a/packages/oas/openapi-typescript-codegen/src/openApi/v3/interfaces/Extensions/WithDefaultRelationsExtension.d.ts +++ b/packages/oas/openapi-typescript-codegen/src/openApi/v3/interfaces/Extensions/WithDefaultRelationsExtension.d.ts @@ -4,5 +4,6 @@ export interface WithExtendedRelationsExtension { relations?: string[] totals?: string[] implicit?: string[] + eager?: string[] } } diff --git a/packages/oas/openapi-typescript-codegen/src/openApi/v3/parser/getModelsExpandedRelations.ts b/packages/oas/openapi-typescript-codegen/src/openApi/v3/parser/getModelsExpandedRelations.ts index e61d966c72..5218fabda0 100644 --- a/packages/oas/openapi-typescript-codegen/src/openApi/v3/parser/getModelsExpandedRelations.ts +++ b/packages/oas/openapi-typescript-codegen/src/openApi/v3/parser/getModelsExpandedRelations.ts @@ -9,13 +9,14 @@ export const handleExpandedRelations = (model: Model, allModels: Model[]) => { const relations = xExpandedRelation.relations ?? [] const totals = xExpandedRelation.totals ?? [] const implicit = xExpandedRelation.implicit ?? [] + const eager = xExpandedRelation.eager ?? [] const nestedRelation: NestedRelation = { field, nestedRelations: [], } - for (const relation of [...relations, ...totals, ...implicit]) { + for (const relation of [...relations, ...totals, ...implicit, ...eager]) { const splitRelation = relation.split(".") walkSplitRelations(nestedRelation, splitRelation, 0) } @@ -24,9 +25,13 @@ export const handleExpandedRelations = (model: Model, allModels: Model[]) => { model.imports = [...new Set(model.imports)] const prop = getPropertyByName(nestedRelation.field, model) - if (prop) { - prop.nestedRelations = [nestedRelation] + if (!prop) { + throw new Error(`x-expanded-relations error - field not found + Schema: ${model.name} + NestedRelation: ${JSON.stringify(nestedRelation, null, 2)} + Model: ${JSON.stringify(model.spec, null, 2)}`) } + prop.nestedRelations = [nestedRelation] } const walkSplitRelations = ( @@ -59,12 +64,20 @@ const walkNestedRelations = ( nestedRelation: NestedRelation, parentNestedRelation?: NestedRelation ) => { - const prop = - model.export === "all-of" - ? findPropInAllOf(nestedRelation.field, model, allModels) - : getPropertyByName(nestedRelation.field, model) + const prop = ["all-of", "any-of", "one-of"].includes(model.export) + ? findPropInCombination(nestedRelation.field, model, allModels) + : getPropertyByName(nestedRelation.field, model) if (!prop) { - return + throw new Error(`x-expanded-relations - field not found + Schema: ${rootModel.name} + NestedRelation: ${JSON.stringify(nestedRelation, null, 2)} + Model: ${JSON.stringify(model.spec, null, 2)}`) + } + if (["all-of", "any-of", "one-of"].includes(prop.export)) { + throw new Error(`x-expanded-relations - unsupported - field referencing multiple models + Schema: ${rootModel.name} + NestedRelation: ${JSON.stringify(nestedRelation, null, 2)} + Model: ${JSON.stringify(model.spec, null, 2)}`) } if (!["reference", "array"].includes(prop.export)) { return @@ -73,15 +86,21 @@ const walkNestedRelations = ( nestedRelation.base = prop.type nestedRelation.isArray = prop.export === "array" + if (!nestedRelation.nestedRelations.length) { + return + } + const childModel = getModelByName(prop.type, allModels) + if (!childModel) { + throw new Error(`x-expanded-relations - field referencing unknown model + Schema: ${rootModel.name} + NestedRelation: ${JSON.stringify(nestedRelation, null, 2)} + Model: ${JSON.stringify(model.spec, null, 2)}`) + } + rootModel.imports.push(prop.type) + if (parentNestedRelation) { + parentNestedRelation.hasDepth = true + } for (const childNestedRelation of nestedRelation.nestedRelations) { - const childModel = getModelByName(prop.type, allModels) - if (!childModel) { - return - } - rootModel.imports.push(prop.type) - if (parentNestedRelation) { - parentNestedRelation.hasDepth = true - } walkNestedRelations( allModels, rootModel, @@ -92,7 +111,7 @@ const walkNestedRelations = ( } } -const findPropInAllOf = ( +const findPropInCombination = ( fieldName: string, model: Model, allModels: Model[] diff --git a/packages/oas/openapi-typescript-codegen/src/templates/core/ModelUtils.hbs b/packages/oas/openapi-typescript-codegen/src/templates/core/ModelUtils.hbs index cc754711e3..2939ce82fd 100644 --- a/packages/oas/openapi-typescript-codegen/src/templates/core/ModelUtils.hbs +++ b/packages/oas/openapi-typescript-codegen/src/templates/core/ModelUtils.hbs @@ -91,4 +91,11 @@ export type SetNonNullable = EnforceOptional< SimpleMerge, PickIndexSignature> & SimpleMerge, OmitIndexSignature> ->; \ No newline at end of file +>; + +/** + * SetRelation + * Alias combining SetRequire and SetNonNullable. + */ +export type SetRelation = + SetRequired, Keys>; \ No newline at end of file diff --git a/packages/oas/openapi-typescript-codegen/src/templates/exportModel.hbs b/packages/oas/openapi-typescript-codegen/src/templates/exportModel.hbs index aba18c7e2e..bb602822e6 100644 --- a/packages/oas/openapi-typescript-codegen/src/templates/exportModel.hbs +++ b/packages/oas/openapi-typescript-codegen/src/templates/exportModel.hbs @@ -1,6 +1,6 @@ {{>header}} -import { SetRequired, Merge } from '../core/ModelUtils'; +import { SetRelation, Merge } from '../core/ModelUtils'; {{#if imports}} {{#each imports}} diff --git a/packages/oas/openapi-typescript-codegen/src/templates/partials/typeWithRelation.hbs b/packages/oas/openapi-typescript-codegen/src/templates/partials/typeWithRelation.hbs index 46ceadef56..380194d93f 100644 --- a/packages/oas/openapi-typescript-codegen/src/templates/partials/typeWithRelation.hbs +++ b/packages/oas/openapi-typescript-codegen/src/templates/partials/typeWithRelation.hbs @@ -1,6 +1,6 @@ {{~#if isArray}}Array<{{/if~}} {{~#if hasDepth}}Merge<{{/if~}} -SetRequired<{{>base}}, {{#each nestedRelations}}'{{{field}}}'{{#unless @last}} | {{/unless}}{{/each}}>{{#if hasDepth}}, { +SetRelation<{{>base}}, {{#each nestedRelations}}'{{{field}}}'{{#unless @last}} | {{/unless}}{{/each}}>{{#if hasDepth}}, { {{/if}} {{~#each nestedRelations~}} {{#if nestedRelations~}}