feat(codegen:test): coverage x-expanded-relation + x-codegen.queryParams (#3675)
## What Adding tests to cover `x-expanded-relation` and `x-codegen.queryParams` handling ## Why The logic that processes these OAS extension can be complex to reason with. Therefore, we should have automated tests to prevent unintentional regression. ## How * Focus on `getModels` method and its sub-routines. * Add coverage to getOperation codegen parsing. * Add coverage to model and operation spec property.
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"@medusajs/openapi-typescript-codegen": patch
|
||||
---
|
||||
|
||||
feat(codegen:test): coverage x-expanded-relation + x-codegen.queryParams
|
||||
@@ -0,0 +1,14 @@
|
||||
module.exports = {
|
||||
globals: {
|
||||
"ts-jest": {
|
||||
tsConfig: "tsconfig.json",
|
||||
isolatedModules: false,
|
||||
},
|
||||
},
|
||||
transform: {
|
||||
"^.+\\.[jt]s?$": "ts-jest",
|
||||
},
|
||||
testEnvironment: `node`,
|
||||
moduleFileExtensions: [`js`, `ts`],
|
||||
testTimeout: 30000,
|
||||
}
|
||||
@@ -22,7 +22,7 @@
|
||||
"prepare": "cross-env NODE_ENV=production yarn run release",
|
||||
"build": "rollup --config --environment NODE_ENV:development",
|
||||
"release": "rollup --config --environment NODE_ENV:production",
|
||||
"test": "jest --passWithNoTests"
|
||||
"test": "jest src"
|
||||
},
|
||||
"dependencies": {
|
||||
"camelcase": "^6.3.0",
|
||||
@@ -49,12 +49,12 @@
|
||||
"abort-controller": "3.0.0",
|
||||
"axios": "1.2.0",
|
||||
"form-data": "4.0.0",
|
||||
"jest": "26.6.3",
|
||||
"jest-cli": "26.6.3",
|
||||
"jest": "^25.5.4",
|
||||
"node-fetch": "2.6.7",
|
||||
"qs": "6.10.3",
|
||||
"rollup": "3.9.1",
|
||||
"rollup-plugin-terser": "7.0.2",
|
||||
"ts-jest": "^25.5.1",
|
||||
"tslib": "2.3.1",
|
||||
"typescript": "4.9.5"
|
||||
}
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@ import type { OpenApiResponse } from "./OpenApiResponse"
|
||||
* https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#responsesObject
|
||||
*/
|
||||
export interface OpenApiResponses extends OpenApiReference {
|
||||
default: OpenApiResponse
|
||||
default?: OpenApiResponse
|
||||
|
||||
[httpcode: string]: OpenApiResponse
|
||||
}
|
||||
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
import { getModel } from "../getModel"
|
||||
import { OpenApi } from "../../interfaces/OpenApi"
|
||||
import { Model } from "../../../../client/interfaces/Model"
|
||||
import { OpenApiSchema } from "../../interfaces/OpenApiSchema"
|
||||
|
||||
describe("getModel", () => {
|
||||
let openApi: OpenApi
|
||||
beforeEach(async () => {
|
||||
openApi = {
|
||||
openapi: "3.0.0",
|
||||
info: {
|
||||
title: "Test",
|
||||
version: "1.0.0",
|
||||
},
|
||||
paths: {},
|
||||
components: {},
|
||||
}
|
||||
})
|
||||
|
||||
it("should set model spec with definition", () => {
|
||||
const modelName = "OrderRes"
|
||||
const definition: OpenApiSchema = {
|
||||
type: "object",
|
||||
properties: {
|
||||
id: {
|
||||
type: "string",
|
||||
},
|
||||
},
|
||||
}
|
||||
const model: Model = getModel(openApi, definition, true, modelName)
|
||||
expect(model.spec).toEqual(definition)
|
||||
})
|
||||
|
||||
it("should set property spec with definition", () => {
|
||||
const modelName = "OrderRes"
|
||||
const definition: OpenApiSchema = {
|
||||
type: "object",
|
||||
properties: {
|
||||
order: {
|
||||
type: "object",
|
||||
properties: {
|
||||
id: {
|
||||
type: "string",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
const model: Model = getModel(openApi, definition, true, modelName)
|
||||
expect(model.properties[0].spec).toEqual(definition.properties!.order)
|
||||
})
|
||||
})
|
||||
+169
@@ -0,0 +1,169 @@
|
||||
import { getModels } from "../getModels"
|
||||
import { OpenApi } from "../../interfaces/OpenApi"
|
||||
|
||||
describe("getModels", () => {
|
||||
let openApi: OpenApi
|
||||
beforeEach(async () => {
|
||||
openApi = {
|
||||
openapi: "3.0.0",
|
||||
info: {
|
||||
title: "Test",
|
||||
version: "1.0.0",
|
||||
},
|
||||
paths: {},
|
||||
components: {},
|
||||
}
|
||||
})
|
||||
|
||||
it("should return an empty array if no models are found", () => {
|
||||
const models = getModels(openApi)
|
||||
expect(models).toEqual([])
|
||||
})
|
||||
|
||||
it("should return an array of models", () => {
|
||||
openApi.components = {
|
||||
schemas: {
|
||||
OrderRes: {
|
||||
type: "object",
|
||||
properties: {
|
||||
id: {
|
||||
type: "string",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
const models = getModels(openApi)
|
||||
expect(models).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
name: "OrderRes",
|
||||
properties: expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
name: "id",
|
||||
type: "string",
|
||||
}),
|
||||
]),
|
||||
}),
|
||||
])
|
||||
)
|
||||
})
|
||||
|
||||
it("should return an array of models with expanded relations", () => {
|
||||
openApi.components = {
|
||||
schemas: {
|
||||
OrderRes: {
|
||||
type: "object",
|
||||
"x-expanded-relations": {
|
||||
field: "order",
|
||||
relations: ["region", "region.country"],
|
||||
},
|
||||
properties: {
|
||||
order: {
|
||||
$ref: "#/components/schemas/Order",
|
||||
},
|
||||
},
|
||||
},
|
||||
Order: {
|
||||
type: "object",
|
||||
properties: {
|
||||
region: {
|
||||
$ref: "#/components/schemas/Region",
|
||||
},
|
||||
},
|
||||
},
|
||||
Region: {
|
||||
type: "object",
|
||||
properties: {
|
||||
country: {
|
||||
$ref: "#/components/schemas/Country",
|
||||
},
|
||||
},
|
||||
},
|
||||
Country: {
|
||||
type: "object",
|
||||
},
|
||||
},
|
||||
}
|
||||
const models = getModels(openApi)
|
||||
expect(models).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
name: "OrderRes",
|
||||
properties: expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
name: "order",
|
||||
base: "Order",
|
||||
nestedRelations: expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
base: "Order",
|
||||
field: "order",
|
||||
nestedRelations: expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
field: "region",
|
||||
base: "Region",
|
||||
nestedRelations: expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
base: "Country",
|
||||
field: "country",
|
||||
nestedRelations: [],
|
||||
}),
|
||||
]),
|
||||
}),
|
||||
]),
|
||||
}),
|
||||
]),
|
||||
}),
|
||||
]),
|
||||
}),
|
||||
])
|
||||
)
|
||||
})
|
||||
|
||||
it("should convert query parameters into a schema when x-codegen.queryParams is declared", () => {
|
||||
openApi.paths = {
|
||||
"/": {
|
||||
get: {
|
||||
operationId: "GetOrder",
|
||||
"x-codegen": {
|
||||
queryParams: "GetOrderQueryParams",
|
||||
},
|
||||
parameters: [
|
||||
{
|
||||
description: "Limit the number of results",
|
||||
in: "query",
|
||||
name: "limit",
|
||||
schema: {
|
||||
type: "integer",
|
||||
},
|
||||
required: true,
|
||||
deprecated: true,
|
||||
},
|
||||
],
|
||||
responses: {
|
||||
"200": {
|
||||
description: "OK",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
const models = getModels(openApi)
|
||||
expect(models).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
name: "GetOrderQueryParams",
|
||||
properties: expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
description: "Limit the number of results",
|
||||
name: "limit",
|
||||
type: "number",
|
||||
isRequired: true,
|
||||
deprecated: true,
|
||||
}),
|
||||
]),
|
||||
}),
|
||||
])
|
||||
)
|
||||
})
|
||||
})
|
||||
+436
@@ -0,0 +1,436 @@
|
||||
import { Model } from "../../../../client/interfaces/Model"
|
||||
import { handleExpandedRelations } from "../getModelsExpandedRelations"
|
||||
import { getModel } from "../getModel"
|
||||
import { OpenApi } from "../../interfaces/OpenApi"
|
||||
import { OpenApiSchema } from "../../interfaces/OpenApiSchema"
|
||||
import { getType } from "../getType"
|
||||
|
||||
function getModelsTest(openApi: OpenApi): Model[] {
|
||||
const models: Model[] = []
|
||||
if (openApi.components) {
|
||||
for (const definitionName in openApi.components.schemas) {
|
||||
if (openApi.components.schemas.hasOwnProperty(definitionName)) {
|
||||
const definition = openApi.components.schemas[definitionName]
|
||||
const definitionType = getType(definitionName)
|
||||
const model = getModel(openApi, definition, true, definitionType.base)
|
||||
models.push(model)
|
||||
}
|
||||
}
|
||||
}
|
||||
return models
|
||||
}
|
||||
|
||||
describe("getModelsExpandedRelations", () => {
|
||||
let openApi: OpenApi
|
||||
beforeEach(async () => {
|
||||
openApi = {
|
||||
openapi: "3.0.0",
|
||||
info: {
|
||||
title: "Test",
|
||||
version: "1.0.0",
|
||||
},
|
||||
paths: {},
|
||||
components: {
|
||||
schemas: {
|
||||
Order: {
|
||||
type: "object",
|
||||
properties: {
|
||||
region: {
|
||||
$ref: "#/components/schemas/Region",
|
||||
},
|
||||
total: {
|
||||
type: "number",
|
||||
},
|
||||
},
|
||||
},
|
||||
Region: {
|
||||
type: "object",
|
||||
properties: {
|
||||
country: {
|
||||
$ref: "#/components/schemas/Country",
|
||||
},
|
||||
},
|
||||
},
|
||||
Country: {
|
||||
type: "object",
|
||||
},
|
||||
Customer: {
|
||||
type: "object",
|
||||
properties: {
|
||||
orders: {
|
||||
type: "array",
|
||||
items: {
|
||||
$ref: "#/components/schemas/Order",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
})
|
||||
|
||||
describe("basic use cases", () => {
|
||||
it("should find nested relation - model", () => {
|
||||
const modelName: string = "OrderRes"
|
||||
const definition: OpenApiSchema = {
|
||||
type: "object",
|
||||
"x-expanded-relations": {
|
||||
field: "order",
|
||||
relations: ["region"],
|
||||
},
|
||||
properties: {
|
||||
order: {
|
||||
$ref: "#/components/schemas/Order",
|
||||
},
|
||||
},
|
||||
}
|
||||
const model: Model = getModel(openApi, definition, true, modelName)
|
||||
const models: Model[] = [...getModelsTest(openApi), model]
|
||||
|
||||
handleExpandedRelations(model, models)
|
||||
|
||||
expect(model.properties[0].nestedRelations).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
field: "order",
|
||||
base: "Order",
|
||||
isArray: false,
|
||||
nestedRelations: expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
field: "region",
|
||||
base: "Region",
|
||||
isArray: false,
|
||||
nestedRelations: [],
|
||||
}),
|
||||
]),
|
||||
}),
|
||||
])
|
||||
)
|
||||
})
|
||||
|
||||
it("should find nested relation - shallow", () => {
|
||||
const modelName: string = "OrderRes"
|
||||
const definition: OpenApiSchema = {
|
||||
type: "object",
|
||||
"x-expanded-relations": {
|
||||
field: "order",
|
||||
relations: ["total"],
|
||||
},
|
||||
properties: {
|
||||
order: {
|
||||
$ref: "#/components/schemas/Order",
|
||||
},
|
||||
},
|
||||
}
|
||||
const model: Model = getModel(openApi, definition, true, modelName)
|
||||
const models: Model[] = [...getModelsTest(openApi), model]
|
||||
|
||||
handleExpandedRelations(model, models)
|
||||
|
||||
expect(model.properties[0].nestedRelations).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
field: "order",
|
||||
base: "Order",
|
||||
isArray: false,
|
||||
nestedRelations: expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
field: "total",
|
||||
nestedRelations: [],
|
||||
}),
|
||||
]),
|
||||
}),
|
||||
])
|
||||
)
|
||||
})
|
||||
|
||||
it("should find nested relation - array", () => {
|
||||
const modelName: string = "CustomerRes"
|
||||
const definition: OpenApiSchema = {
|
||||
type: "object",
|
||||
"x-expanded-relations": {
|
||||
field: "customer",
|
||||
relations: ["orders"],
|
||||
},
|
||||
properties: {
|
||||
customer: {
|
||||
$ref: "#/components/schemas/Customer",
|
||||
},
|
||||
},
|
||||
}
|
||||
const model: Model = getModel(openApi, definition, true, modelName)
|
||||
const models: Model[] = [...getModelsTest(openApi), model]
|
||||
|
||||
handleExpandedRelations(model, models)
|
||||
|
||||
expect(model.properties[0].nestedRelations).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
field: "customer",
|
||||
base: "Customer",
|
||||
isArray: false,
|
||||
nestedRelations: expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
field: "orders",
|
||||
base: "Order",
|
||||
isArray: true,
|
||||
nestedRelations: [],
|
||||
}),
|
||||
]),
|
||||
}),
|
||||
])
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe("misc usage", () => {
|
||||
it.each([["allOf"], ["anyOf"], ["oneOf"]])(
|
||||
"should findPropInCombination - %s",
|
||||
(combination) => {
|
||||
openApi.components!.schemas!.ExpandedOrder = {
|
||||
[combination]: [{ $ref: "#/components/schemas/Order" }],
|
||||
}
|
||||
const modelName: string = "OrderRes"
|
||||
const definition: OpenApiSchema = {
|
||||
type: "object",
|
||||
"x-expanded-relations": {
|
||||
field: "order",
|
||||
relations: ["region"],
|
||||
},
|
||||
properties: {
|
||||
order: {
|
||||
$ref: "#/components/schemas/ExpandedOrder",
|
||||
},
|
||||
},
|
||||
}
|
||||
const model: Model = getModel(openApi, definition, true, modelName)
|
||||
const models: Model[] = [...getModelsTest(openApi), model]
|
||||
|
||||
handleExpandedRelations(model, models)
|
||||
|
||||
expect(model.properties[0].nestedRelations).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
nestedRelations: expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
field: "region",
|
||||
}),
|
||||
]),
|
||||
}),
|
||||
])
|
||||
)
|
||||
}
|
||||
)
|
||||
|
||||
it.each([["relations"], ["totals"], ["implicit"], ["eager"]])(
|
||||
"should find nested relation with relation type - %s",
|
||||
(relationType) => {
|
||||
const modelName: string = "OrderRes"
|
||||
const definition: OpenApiSchema = {
|
||||
type: "object",
|
||||
"x-expanded-relations": {
|
||||
field: "order",
|
||||
[relationType]: ["region"],
|
||||
},
|
||||
properties: {
|
||||
order: {
|
||||
$ref: "#/components/schemas/Order",
|
||||
},
|
||||
},
|
||||
}
|
||||
const model: Model = getModel(openApi, definition, true, modelName)
|
||||
const models: Model[] = [...getModelsTest(openApi), model]
|
||||
|
||||
handleExpandedRelations(model, models)
|
||||
|
||||
expect(model.properties[0].nestedRelations).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
nestedRelations: expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
field: "region",
|
||||
}),
|
||||
]),
|
||||
}),
|
||||
])
|
||||
)
|
||||
}
|
||||
)
|
||||
|
||||
it("should set field hasDepth - true", () => {
|
||||
const modelName: string = "OrderRes"
|
||||
const definition: OpenApiSchema = {
|
||||
type: "object",
|
||||
"x-expanded-relations": {
|
||||
field: "order",
|
||||
relations: ["region.country"],
|
||||
},
|
||||
properties: {
|
||||
order: {
|
||||
$ref: "#/components/schemas/Order",
|
||||
},
|
||||
},
|
||||
}
|
||||
const model: Model = getModel(openApi, definition, true, modelName)
|
||||
const models: Model[] = [...getModelsTest(openApi), model]
|
||||
|
||||
handleExpandedRelations(model, models)
|
||||
|
||||
expect(model.properties[0].nestedRelations).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
hasDepth: true,
|
||||
nestedRelations: expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
field: "region",
|
||||
nestedRelations: expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
field: "country",
|
||||
}),
|
||||
]),
|
||||
}),
|
||||
]),
|
||||
}),
|
||||
])
|
||||
)
|
||||
})
|
||||
|
||||
it("should set relation hasDepth - true", () => {
|
||||
const modelName: string = "CustomerRes"
|
||||
const definition: OpenApiSchema = {
|
||||
type: "object",
|
||||
"x-expanded-relations": {
|
||||
field: "customer",
|
||||
relations: ["orders.region.country"],
|
||||
},
|
||||
properties: {
|
||||
customer: {
|
||||
$ref: "#/components/schemas/Customer",
|
||||
},
|
||||
},
|
||||
}
|
||||
const model: Model = getModel(openApi, definition, true, modelName)
|
||||
const models: Model[] = [...getModelsTest(openApi), model]
|
||||
|
||||
handleExpandedRelations(model, models)
|
||||
|
||||
expect(model.properties[0].nestedRelations).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
hasDepth: true,
|
||||
nestedRelations: expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
field: "orders",
|
||||
hasDepth: true,
|
||||
nestedRelations: expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
field: "region",
|
||||
nestedRelations: expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
field: "country",
|
||||
nestedRelations: [],
|
||||
}),
|
||||
]),
|
||||
}),
|
||||
]),
|
||||
}),
|
||||
]),
|
||||
}),
|
||||
])
|
||||
)
|
||||
})
|
||||
|
||||
it("should add models with relation to root model imports, only once", () => {
|
||||
const modelName: string = "OrderRes"
|
||||
const definition: OpenApiSchema = {
|
||||
type: "object",
|
||||
"x-expanded-relations": {
|
||||
field: "order",
|
||||
relations: ["region", "region.country"],
|
||||
},
|
||||
properties: {
|
||||
order: {
|
||||
$ref: "#/components/schemas/Order",
|
||||
},
|
||||
},
|
||||
}
|
||||
const model: Model = getModel(openApi, definition, true, modelName)
|
||||
const models: Model[] = [...getModelsTest(openApi), model]
|
||||
|
||||
handleExpandedRelations(model, models)
|
||||
|
||||
expect(model.imports).toEqual(expect.arrayContaining(["Order", "Region"]))
|
||||
})
|
||||
})
|
||||
|
||||
describe("errors", () => {
|
||||
it("should throw if field is not found", () => {
|
||||
const modelName: string = "OrderRes"
|
||||
const definition: OpenApiSchema = {
|
||||
type: "object",
|
||||
"x-expanded-relations": {
|
||||
field: "nope",
|
||||
},
|
||||
properties: {
|
||||
order: {
|
||||
$ref: "#/components/schemas/Order",
|
||||
},
|
||||
},
|
||||
}
|
||||
const model: Model = getModel(openApi, definition, true, modelName)
|
||||
const models: Model[] = [...getModelsTest(openApi), model]
|
||||
|
||||
expect(() => handleExpandedRelations(model, models)).toThrow(
|
||||
"x-expanded-relations - field not found"
|
||||
)
|
||||
})
|
||||
|
||||
it("should throw if relation is not found", () => {
|
||||
const modelName: string = "OrderRes"
|
||||
const definition: OpenApiSchema = {
|
||||
type: "object",
|
||||
"x-expanded-relations": {
|
||||
field: "order",
|
||||
relations: ["nope"],
|
||||
},
|
||||
properties: {
|
||||
order: {
|
||||
$ref: "#/components/schemas/Order",
|
||||
},
|
||||
},
|
||||
}
|
||||
const model: Model = getModel(openApi, definition, true, modelName)
|
||||
const models: Model[] = [...getModelsTest(openApi), model]
|
||||
|
||||
expect(() => handleExpandedRelations(model, models)).toThrow(
|
||||
"x-expanded-relations - relation not found"
|
||||
)
|
||||
})
|
||||
|
||||
it.each([["allOf"], ["anyOf"], ["oneOf"]])(
|
||||
"should throw if field exports as a combination - %s",
|
||||
(combination) => {
|
||||
const modelName: string = "OrderRes"
|
||||
const definition: OpenApiSchema = {
|
||||
type: "object",
|
||||
"x-expanded-relations": {
|
||||
field: "order",
|
||||
relations: ["region"],
|
||||
},
|
||||
properties: {
|
||||
order: {
|
||||
[combination]: [{ $ref: "#/components/schemas/Order" }],
|
||||
},
|
||||
},
|
||||
}
|
||||
const model: Model = getModel(openApi, definition, true, modelName)
|
||||
const models: Model[] = [...getModelsTest(openApi), model]
|
||||
|
||||
expect(() => handleExpandedRelations(model, models)).toThrow(
|
||||
"x-expanded-relations - unsupported - field referencing multiple models"
|
||||
)
|
||||
}
|
||||
)
|
||||
})
|
||||
})
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
import { OpenApi } from "../../interfaces/OpenApi"
|
||||
import { OpenApiOperation } from "../../interfaces/OpenApiOperation"
|
||||
import { getOperation } from "../getOperation"
|
||||
import { getOperationParameters } from "../getOperationParameters"
|
||||
|
||||
describe("getOperation", () => {
|
||||
let openApi: OpenApi
|
||||
beforeEach(async () => {
|
||||
openApi = {
|
||||
openapi: "3.0.0",
|
||||
info: {
|
||||
title: "Test",
|
||||
version: "1.0.0",
|
||||
},
|
||||
paths: {},
|
||||
components: {},
|
||||
}
|
||||
})
|
||||
|
||||
it("should parse x-codegen", () => {
|
||||
const op: OpenApiOperation = {
|
||||
"x-codegen": {
|
||||
method: "list",
|
||||
},
|
||||
responses: {
|
||||
"200": {
|
||||
description: "OK",
|
||||
},
|
||||
},
|
||||
}
|
||||
const pathParams = getOperationParameters(openApi, [])
|
||||
const operation = getOperation(
|
||||
openApi,
|
||||
"/orders",
|
||||
"get",
|
||||
"Orders",
|
||||
op,
|
||||
pathParams
|
||||
)
|
||||
expect(operation).toEqual(
|
||||
expect.objectContaining({
|
||||
codegen: { method: "list" },
|
||||
})
|
||||
)
|
||||
})
|
||||
|
||||
it("should add x-codegen.queryParams to imports", () => {
|
||||
const op: OpenApiOperation = {
|
||||
"x-codegen": {
|
||||
queryParams: "OrdersQueryParams",
|
||||
},
|
||||
responses: {
|
||||
"200": {
|
||||
description: "OK",
|
||||
},
|
||||
},
|
||||
}
|
||||
const pathParams = getOperationParameters(openApi, [])
|
||||
const operation = getOperation(
|
||||
openApi,
|
||||
"/orders",
|
||||
"get",
|
||||
"Orders",
|
||||
op,
|
||||
pathParams
|
||||
)
|
||||
expect(operation.imports).toEqual(
|
||||
expect.arrayContaining(["OrdersQueryParams"])
|
||||
)
|
||||
})
|
||||
})
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
import { OpenApi } from "../../interfaces/OpenApi"
|
||||
import { getOperationParameter } from "../getOperationParameter"
|
||||
import { OpenApiParameter } from "../../interfaces/OpenApiParameter"
|
||||
|
||||
describe("getOperation", () => {
|
||||
let openApi: OpenApi
|
||||
beforeEach(async () => {
|
||||
openApi = {
|
||||
openapi: "3.0.0",
|
||||
info: {
|
||||
title: "Test",
|
||||
version: "1.0.0",
|
||||
},
|
||||
paths: {},
|
||||
components: {},
|
||||
}
|
||||
})
|
||||
|
||||
it("should set spec with definition", () => {
|
||||
const parameter: OpenApiParameter = {
|
||||
name: "id",
|
||||
in: "path",
|
||||
}
|
||||
const operationParameter = getOperationParameter(openApi, parameter)
|
||||
expect(operationParameter.spec).toEqual(parameter)
|
||||
})
|
||||
})
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
import { OpenApi } from "../../interfaces/OpenApi"
|
||||
import { getOperationRequestBody } from "../getOperationRequestBody"
|
||||
import { OpenApiRequestBody } from "../../interfaces/OpenApiRequestBody"
|
||||
|
||||
describe("getOperation", () => {
|
||||
let openApi: OpenApi
|
||||
beforeEach(async () => {
|
||||
openApi = {
|
||||
openapi: "3.0.0",
|
||||
info: {
|
||||
title: "Test",
|
||||
version: "1.0.0",
|
||||
},
|
||||
paths: {},
|
||||
components: {},
|
||||
}
|
||||
})
|
||||
|
||||
it("should set spec with definition", () => {
|
||||
const body: OpenApiRequestBody = {
|
||||
content: {
|
||||
"application/json": {
|
||||
schema: {
|
||||
type: "object",
|
||||
properties: {
|
||||
id: {
|
||||
type: "string",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
const operationRequestBody = getOperationRequestBody(openApi, body)
|
||||
expect(operationRequestBody.spec).toEqual(body)
|
||||
})
|
||||
})
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
import { OpenApi } from "../../interfaces/OpenApi"
|
||||
import { getOperationResponse } from "../getOperationResponse"
|
||||
import { OpenApiResponse } from "../../interfaces/OpenApiResponse"
|
||||
|
||||
describe("getOperation", () => {
|
||||
let openApi: OpenApi
|
||||
beforeEach(async () => {
|
||||
openApi = {
|
||||
openapi: "3.0.0",
|
||||
info: {
|
||||
title: "Test",
|
||||
version: "1.0.0",
|
||||
},
|
||||
paths: {},
|
||||
components: {},
|
||||
}
|
||||
})
|
||||
|
||||
it("should set spec with definition", () => {
|
||||
const response: OpenApiResponse = {
|
||||
description: "OK",
|
||||
}
|
||||
const operationResponse = getOperationResponse(openApi, response, 200)
|
||||
expect(operationResponse.spec).toEqual(response)
|
||||
})
|
||||
})
|
||||
@@ -38,7 +38,7 @@ export const getModelProperties = (
|
||||
| "enums"
|
||||
| "properties"
|
||||
> = {
|
||||
spec: definition,
|
||||
spec: property,
|
||||
name: escapeName(propertyName),
|
||||
description: property.description || null,
|
||||
deprecated: property.deprecated === true,
|
||||
|
||||
+15
-6
@@ -21,16 +21,21 @@ export const handleExpandedRelations = (model: Model, allModels: Model[]) => {
|
||||
walkSplitRelations(nestedRelation, splitRelation, 0)
|
||||
}
|
||||
|
||||
walkNestedRelations(allModels, model, model, nestedRelation)
|
||||
model.imports = [...new Set(model.imports)]
|
||||
|
||||
const prop = getPropertyByName(nestedRelation.field, model)
|
||||
if (!prop) {
|
||||
throw new Error(`x-expanded-relations error - field not found
|
||||
throw new Error(`x-expanded-relations - field not found
|
||||
Schema: ${model.name}
|
||||
NestedRelation: ${JSON.stringify(nestedRelation, null, 2)}
|
||||
Model: ${JSON.stringify(model.spec, null, 2)}`)
|
||||
}
|
||||
|
||||
walkNestedRelations(allModels, model, model, nestedRelation)
|
||||
model.imports = [...new Set(model.imports)]
|
||||
/**
|
||||
* To reduce complexity in the exportInterface template, nestedRelations is
|
||||
* set on the property that is the root of the nested relations instead of
|
||||
* setting it on the model.
|
||||
*/
|
||||
prop.nestedRelations = [nestedRelation]
|
||||
}
|
||||
|
||||
@@ -63,17 +68,21 @@ const walkNestedRelations = (
|
||||
model: Model,
|
||||
nestedRelation: NestedRelation,
|
||||
parentNestedRelation?: NestedRelation
|
||||
) => {
|
||||
): void => {
|
||||
const prop = ["all-of", "any-of", "one-of"].includes(model.export)
|
||||
? findPropInCombination(nestedRelation.field, model, allModels)
|
||||
: getPropertyByName(nestedRelation.field, model)
|
||||
if (!prop) {
|
||||
throw new Error(`x-expanded-relations - field not found
|
||||
throw new Error(`x-expanded-relations - relation 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)) {
|
||||
/**
|
||||
* Root property for nested relations can not use combination strategies.
|
||||
* To use combination, they must be defined in referenced models instead.
|
||||
*/
|
||||
throw new Error(`x-expanded-relations - unsupported - field referencing multiple models
|
||||
Schema: ${rootModel.name}
|
||||
NestedRelation: ${JSON.stringify(nestedRelation, null, 2)}
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"include": ["src"],
|
||||
"exclude": ["node_modules"]
|
||||
}
|
||||
@@ -5997,14 +5997,14 @@ __metadata:
|
||||
form-data: 4.0.0
|
||||
fs-extra: ^10.1.0
|
||||
handlebars: ^4.7.7
|
||||
jest: 26.6.3
|
||||
jest-cli: 26.6.3
|
||||
jest: ^25.5.4
|
||||
json-schema-ref-parser: ^9.0.9
|
||||
node-fetch: 2.6.7
|
||||
pascalcase: ^2.0.0
|
||||
qs: 6.10.3
|
||||
rollup: 3.9.1
|
||||
rollup-plugin-terser: 7.0.2
|
||||
ts-jest: ^25.5.1
|
||||
tslib: 2.3.1
|
||||
typescript: 4.9.5
|
||||
languageName: unknown
|
||||
@@ -24599,29 +24599,6 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"jest-cli@npm:26.6.3, jest-cli@npm:^26.6.3":
|
||||
version: 26.6.3
|
||||
resolution: "jest-cli@npm:26.6.3"
|
||||
dependencies:
|
||||
"@jest/core": ^26.6.3
|
||||
"@jest/test-result": ^26.6.2
|
||||
"@jest/types": ^26.6.2
|
||||
chalk: ^4.0.0
|
||||
exit: ^0.1.2
|
||||
graceful-fs: ^4.2.4
|
||||
import-local: ^3.0.2
|
||||
is-ci: ^2.0.0
|
||||
jest-config: ^26.6.3
|
||||
jest-util: ^26.6.2
|
||||
jest-validate: ^26.6.2
|
||||
prompts: ^2.0.1
|
||||
yargs: ^15.4.1
|
||||
bin:
|
||||
jest: bin/jest.js
|
||||
checksum: 3f62c26b300549115bcfc0393d7d49467d414d200bb211a8843fd48d0296ddbfc5e6fe808c64ad2039127657b662e3ba3db44166341bd5db2d089bf09cf82a2c
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"jest-cli@npm:^25.5.4":
|
||||
version: 25.5.4
|
||||
resolution: "jest-cli@npm:25.5.4"
|
||||
@@ -24646,6 +24623,29 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"jest-cli@npm:^26.6.3":
|
||||
version: 26.6.3
|
||||
resolution: "jest-cli@npm:26.6.3"
|
||||
dependencies:
|
||||
"@jest/core": ^26.6.3
|
||||
"@jest/test-result": ^26.6.2
|
||||
"@jest/types": ^26.6.2
|
||||
chalk: ^4.0.0
|
||||
exit: ^0.1.2
|
||||
graceful-fs: ^4.2.4
|
||||
import-local: ^3.0.2
|
||||
is-ci: ^2.0.0
|
||||
jest-config: ^26.6.3
|
||||
jest-util: ^26.6.2
|
||||
jest-validate: ^26.6.2
|
||||
prompts: ^2.0.1
|
||||
yargs: ^15.4.1
|
||||
bin:
|
||||
jest: bin/jest.js
|
||||
checksum: 3f62c26b300549115bcfc0393d7d49467d414d200bb211a8843fd48d0296ddbfc5e6fe808c64ad2039127657b662e3ba3db44166341bd5db2d089bf09cf82a2c
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"jest-cli@npm:^27.5.1":
|
||||
version: 27.5.1
|
||||
resolution: "jest-cli@npm:27.5.1"
|
||||
@@ -26298,19 +26298,6 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"jest@npm:26.6.3, jest@npm:^26.6.3":
|
||||
version: 26.6.3
|
||||
resolution: "jest@npm:26.6.3"
|
||||
dependencies:
|
||||
"@jest/core": ^26.6.3
|
||||
import-local: ^3.0.2
|
||||
jest-cli: ^26.6.3
|
||||
bin:
|
||||
jest: bin/jest.js
|
||||
checksum: 4469f5c426f5b00855e2264dc4fce5ab16c0fab31d2dc6fc829d769ca7ec84a9c74763f7c1d281d085ad55897927a08df2b4778b0df899a66188ff0722e17d29
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"jest@npm:^25.5.2, jest@npm:^25.5.4":
|
||||
version: 25.5.4
|
||||
resolution: "jest@npm:25.5.4"
|
||||
@@ -26324,6 +26311,19 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"jest@npm:^26.6.3":
|
||||
version: 26.6.3
|
||||
resolution: "jest@npm:26.6.3"
|
||||
dependencies:
|
||||
"@jest/core": ^26.6.3
|
||||
import-local: ^3.0.2
|
||||
jest-cli: ^26.6.3
|
||||
bin:
|
||||
jest: bin/jest.js
|
||||
checksum: 4469f5c426f5b00855e2264dc4fce5ab16c0fab31d2dc6fc829d769ca7ec84a9c74763f7c1d281d085ad55897927a08df2b4778b0df899a66188ff0722e17d29
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"jest@npm:^27.0.6, jest@npm:^27.4.7":
|
||||
version: 27.5.1
|
||||
resolution: "jest@npm:27.5.1"
|
||||
|
||||
Reference in New Issue
Block a user