Skip to content

Commit

Permalink
Merge branch 'develop' into oas/improve-oas-schemas-15
Browse files Browse the repository at this point in the history
  • Loading branch information
shahednasser authored Sep 23, 2024
2 parents 0d3a125 + cebffc7 commit d08bd9d
Show file tree
Hide file tree
Showing 78 changed files with 1,510 additions and 696 deletions.
3 changes: 3 additions & 0 deletions packages/cli/oas/medusa-oas-cli/redocly/redocly-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ decorators:
- ProductCategoryResponse
AdminShippingOption:
- AdminShippingOption
- AdminServiceZone
AdminProductCategory:
- AdminProductCategory
- AdminProduct
Expand All @@ -41,6 +42,8 @@ decorators:
AdminTaxRegion:
- AdminTaxRegion
- AdminTaxRate
AdminInventoryLevel:
- AdminInventoryItem
theme:
openapi:
theme:
Expand Down
11 changes: 7 additions & 4 deletions packages/cli/oas/medusa-oas-cli/src/command-docs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -238,10 +238,13 @@ ${hint}
`
const redoclyConfigPath = path.join(basePath, "redocly", "redocly-config.yaml")
const originalContent = await readYaml(redoclyConfigPath) as CircularReferenceConfig
originalContent.decorators["medusa/circular-patch"].schemas = Object.assign(
originalContent.decorators["medusa/circular-patch"].schemas,
recommendation
)
Object.keys(recommendation).forEach((recKey) => {
originalContent.decorators["medusa/circular-patch"].schemas[recKey] = [
...(originalContent.decorators["medusa/circular-patch"].schemas[recKey] || []),
...recommendation[recKey]
]
})

await writeYaml(redoclyConfigPath, jsonObjectToYamlString(originalContent))
console.log(`🟡 Added the following unhandled circular references to redocly-config.ts:` + hintMessage)
}
Expand Down
55 changes: 22 additions & 33 deletions packages/framework/framework/src/http/router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ import {
} from "express"
import { readdir } from "fs/promises"
import { extname, join, parse, sep } from "path"
import { configManager } from "../config"
import { logger } from "../logger"
import { authenticate, AuthType, errorHandler } from "./middlewares"
import {
GlobalMiddlewareDescriptor,
HTTP_METHODS,
Expand All @@ -25,9 +28,6 @@ import {
RouteHandler,
RouteVerb,
} from "./types"
import { authenticate, AuthType, errorHandler } from "./middlewares"
import { configManager } from "../config"
import { logger } from "../logger"

const log = ({
activityId,
Expand Down Expand Up @@ -486,43 +486,32 @@ class ApiRoutesLoader {

const absolutePath = join(this.#sourceDir, middlewareFilePath)

try {
await import(absolutePath).then((import_) => {
const middlewaresConfig = import_.default as
| MiddlewaresConfig
| undefined

if (!middlewaresConfig) {
log({
activityId: this.#activityId,
message: `No middleware configuration found in ${absolutePath}. Skipping middleware configuration.`,
})
return
}
await import(absolutePath).then((import_) => {
const middlewaresConfig = import_.default as MiddlewaresConfig | undefined

middlewaresConfig.routes = middlewaresConfig.routes?.map((route) => {
return {
...route,
method: route.method ?? "USE",
}
if (!middlewaresConfig) {
log({
activityId: this.#activityId,
message: `No middleware configuration found in ${absolutePath}. Skipping middleware configuration.`,
})
return
}

const descriptor: GlobalMiddlewareDescriptor = {
config: middlewaresConfig,
middlewaresConfig.routes = middlewaresConfig.routes?.map((route) => {
return {
...route,
method: route.method ?? "USE",
}
})

this.validateMiddlewaresConfig(descriptor)
const descriptor: GlobalMiddlewareDescriptor = {
config: middlewaresConfig,
}

this.#globalMiddlewaresDescriptor = descriptor
})
} catch (error) {
log({
activityId: this.#activityId,
message: `Failed to load middleware configuration in ${absolutePath}. Skipping middleware configuration.`,
})
this.validateMiddlewaresConfig(descriptor)

return
}
this.#globalMiddlewaresDescriptor = descriptor
})
}

protected async createRoutesMap(): Promise<void> {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
"use client"

import type { SchemaObject } from "@/types/openapi"
import TagOperationParametersDefault from "../Default"
import dynamic from "next/dynamic"
import type { TagOperationParametersProps } from "../.."
import type { TagsOperationParametersNestedProps } from "../../Nested"
import checkRequired from "@/utils/check-required"
import { Loading, type DetailsProps } from "docs-ui"
import { useMemo } from "react"

const TagOperationParameters = dynamic<TagOperationParametersProps>(
async () => import("../.."),
Expand Down Expand Up @@ -41,9 +44,22 @@ const TagOperationParametersObject = ({
isRequired,
topLevel = false,
}: TagOperationParametersObjectProps) => {
const isPropertiesEmpty = useMemo(
() => !schema.properties || !Object.values(schema.properties).length,
[schema]
)
const isAdditionalPropertiesEmpty = useMemo(
() =>
!schema.additionalProperties ||
schema.additionalProperties.type !== "object" ||
!schema.additionalProperties.properties ||
!Object.values(schema.additionalProperties.properties).length,
[schema]
)

if (
(schema.type !== "object" && schema.type !== undefined) ||
(!schema.properties && !name)
(isPropertiesEmpty && isAdditionalPropertiesEmpty && !name)
) {
return <></>
}
Expand All @@ -65,22 +81,19 @@ const TagOperationParametersObject = ({
}

const getPropertyParameterElms = (isNested = false) => {
const properties = isPropertiesEmpty
? schema.additionalProperties!.properties
: schema.properties
// sort properties to show required fields first
const sortedProperties = Object.keys(schema.properties).sort(
const sortedProperties = Object.keys(properties).sort(
(property1, property2) => {
schema.properties[property1].isRequired = checkRequired(
schema,
property1
)
schema.properties[property2].isRequired = checkRequired(
schema,
property2
)
properties[property1].isRequired = checkRequired(schema, property1)
properties[property2].isRequired = checkRequired(schema, property2)

return schema.properties[property1].isRequired &&
schema.properties[property2].isRequired
return properties[property1].isRequired &&
properties[property2].isRequired
? 0
: schema.properties[property1].isRequired
: properties[property1].isRequired
? -1
: 1
}
Expand All @@ -90,13 +103,12 @@ const TagOperationParametersObject = ({
{sortedProperties.map((property, index) => (
<TagOperationParameters
schemaObject={{
...schema.properties[property],
...properties[property],
parameterName: property,
}}
key={index}
isRequired={
schema.properties[property].isRequired ||
checkRequired(schema, property)
properties[property].isRequired || checkRequired(schema, property)
}
/>
))}
Expand All @@ -114,7 +126,7 @@ const TagOperationParametersObject = ({
)
}

if (!schema.properties || !Object.values(schema.properties).length) {
if (isPropertiesEmpty && isAdditionalPropertiesEmpty) {
return getPropertyDescriptionElm()
}

Expand Down
9 changes: 8 additions & 1 deletion www/apps/api-reference/types/openapi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,15 @@ export type ArraySchemaObject = Omit<

export type NonArraySchemaObject = Omit<
OpenAPIV3.NonArraySchemaObject,
"properties" | "anyOf" | "allOf" | "oneOf" | "examples"
| "properties"
| "anyOf"
| "allOf"
| "oneOf"
| "examples"
| "additionalProperties"
> & {
properties: PropertiesObject
additionalProperties?: SchemaObject
anyOf?: SchemaObject[]
allOf?: SchemaObject[]
oneOf?: SchemaObject[]
Expand All @@ -90,6 +96,7 @@ export type SchemaObject = (ArraySchemaObject | NonArraySchemaObject) & {
"x-featureFlag"?: string
"x-expandable"?: string
"x-schemaName"?: string
additionalProperties?: SchemaObject
}

export type PropertiesObject = {
Expand Down
Loading

0 comments on commit d08bd9d

Please sign in to comment.