Skip to content

Commit

Permalink
refactor: move toJSON method to operationMapper.ts
Browse files Browse the repository at this point in the history
  • Loading branch information
Romakita committed Aug 2, 2023
1 parent 5051300 commit 5c15da0
Show file tree
Hide file tree
Showing 31 changed files with 403 additions and 301 deletions.
6 changes: 3 additions & 3 deletions packages/specs/schema/jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ module.exports = {
roots: ["<rootDir>/src", "<rootDir>/test"],
coverageThreshold: {
global: {
statements: 99.45,
branches: 96.16,
statements: 99.46,
branches: 96.23,
functions: 100,
lines: 99.45
lines: 99.46
}
},
moduleNameMapper: {
Expand Down
7 changes: 4 additions & 3 deletions packages/specs/schema/src/components/anyMapper.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {JsonLazyRef} from "../domain/JsonLazyRef";
import {JsonSchema} from "../domain/JsonSchema";
import {JsonSchemaOptions} from "../interfaces/JsonSchemaOptions";
import {execMapper, registerJsonSchemaMapper} from "../registries/JsonSchemaMapperContainer";
import {execMapper, oneOfMapper, registerJsonSchemaMapper} from "../registries/JsonSchemaMapperContainer";
import {mapGenericsOptions} from "../utils/generics";
import {toRef} from "../utils/ref";

Expand All @@ -20,8 +20,9 @@ export function anyMapper(input: any, options: JsonSchemaOptions = {}): any {
return toRef(enumSchema, enumSchema.toJSON(options), options);
}

if ("toJSON" in input) {
const schema = input.toJSON(mapGenericsOptions(options));
if (input.kind) {
const kind = oneOfMapper(input.kind, "map");
const schema = execMapper(kind, input, mapGenericsOptions(options));

return input.canRef ? toRef(input, schema, options) : schema;
}
Expand Down
7 changes: 6 additions & 1 deletion packages/specs/schema/src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,13 @@ export * from "./mapMapper";
export * from "./objectMapper";
export * from "./ofMapper";
export * from "./operationInFilesMapper";
export * from "./operationInParameterMapper";
export * from "./operationInParametersMapper";
export * from "./operationInQueryMapper";
export * from "./operationParameterMapper";
export * from "./operationMapper";
export * from "./operationMediaMapper";
export * from "./operationRequestBodyMapper";
export * from "./operationResponseMapper";
export * from "./pathsMapper";
export * from "./propertiesMapper";
export * from "./schemaMapper";
16 changes: 8 additions & 8 deletions packages/specs/schema/src/components/lazyRefMapper.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
import {JsonLazyRef} from "../domain/JsonLazyRef";
import {JsonSchemaOptions} from "../interfaces/JsonSchemaOptions";
import {registerJsonSchemaMapper} from "../registries/JsonSchemaMapperContainer";
import {execMapper, registerJsonSchemaMapper} from "../registries/JsonSchemaMapperContainer";
import {mapGenericsOptions} from "../utils/generics";
import {createRef, toRef} from "../utils/ref";

export function lazyRefMapper(input: JsonLazyRef, options: JsonSchemaOptions) {
const name = input.name;
export function lazyRefMapper(jsonLazyRef: JsonLazyRef, options: JsonSchemaOptions) {
const name = jsonLazyRef.name;

if (options.$refs?.find((t: any) => t === input.target)) {
return createRef(name, input.schema, options);
if (options.$refs?.find((t: any) => t === jsonLazyRef.target)) {
return createRef(name, jsonLazyRef.schema, options);
}

options.$refs = [...(options.$refs || []), input.target];
options.$refs = [...(options.$refs || []), jsonLazyRef.target];

const schema = input.toJSON(mapGenericsOptions(options));
const schema = jsonLazyRef.getType() && execMapper("schema", jsonLazyRef.schema, mapGenericsOptions(options));

return toRef(input.schema, schema, options);
return toRef(jsonLazyRef.schema, schema, options);
}

registerJsonSchemaMapper("lazyRef", lazyRefMapper);
2 changes: 1 addition & 1 deletion packages/specs/schema/src/components/mapMapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {execMapper, registerJsonSchemaMapper} from "../registries/JsonSchemaMapp
* @param options
* @ignore
*/
export function mapMapper(input: Map<string, any>, {ignore = [], ...options}: JsonSchemaOptions): any {
export function mapMapper(input: Map<string, any>, {ignore = [], ...options}: JsonSchemaOptions = {}): any {
options = mapGenericsOptions(options);

return Array.from(input.entries()).reduce((obj: any, [key, value]) => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {cleanObject} from "@tsed/core";
import {registerJsonSchemaMapper} from "../registries/JsonSchemaMapperContainer";
import type {JsonParameterOptions} from "./operationParameterMapper";
import type {JsonParameterOptions} from "./operationInParameterMapper";

export function operationInFilesMapper(parameter: any, {jsonSchema}: JsonParameterOptions) {
const schema = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import {OS3Schema} from "@tsed/openspec";
import {camelCase} from "change-case";
import type {JSONSchema6} from "json-schema";
import {JsonParameter} from "../domain/JsonParameter";
import {isParameterType, JsonParameterTypes} from "../domain/JsonParameterTypes";
import {JsonParameterTypes} from "../domain/JsonParameterTypes";
import {JsonSchemaOptions} from "../interfaces/JsonSchemaOptions";
import {execMapper, hasMapper, registerJsonSchemaMapper} from "../registries/JsonSchemaMapperContainer";
import {popGenerics} from "../utils/generics";
Expand All @@ -21,11 +21,7 @@ function mapOptions(parameter: JsonParameter, options: JsonSchemaOptions = {}) {
};
}

export function operationParameterMapper(jsonParameter: JsonParameter, opts?: JsonSchemaOptions) {
if (!isParameterType(jsonParameter.get("in"))) {
return null;
}

export function operationInParameterMapper(jsonParameter: JsonParameter, opts?: JsonSchemaOptions) {
const options = mapOptions(jsonParameter, opts);
const schemas = {...(options.schemas || {})};

Expand Down Expand Up @@ -56,4 +52,4 @@ export function operationParameterMapper(jsonParameter: JsonParameter, opts?: Js
return parameter;
}

registerJsonSchemaMapper("operationParameter", operationParameterMapper);
registerJsonSchemaMapper("operationInParameter", operationInParameterMapper);
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import {JsonParameter} from "../domain/JsonParameter";
import {JsonSchemaOptions} from "../interfaces/JsonSchemaOptions";
import {execMapper, registerJsonSchemaMapper} from "../registries/JsonSchemaMapperContainer";

export function operationInParametersMapper(parameters: JsonParameter[], options: JsonSchemaOptions) {
return parameters.flatMap((parameter) => execMapper("operationInParameter", parameter, options)).filter(Boolean);
}

registerJsonSchemaMapper("operationInParameters", operationInParametersMapper);
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import {cleanObject} from "@tsed/core";
import {JsonSchemaOptions} from "../interfaces/JsonSchemaOptions";
import {registerJsonSchemaMapper} from "../registries/JsonSchemaMapperContainer";
import {createRefName} from "../utils/ref";
import type {JsonParameterOptions} from "./operationParameterMapper";
import type {JsonParameterOptions} from "./operationInParameterMapper";

function inlineReference(parameter: any, {jsonParameter, ...options}: JsonSchemaOptions) {
const name = createRefName(jsonParameter.$schema.getName(), options);
Expand Down
65 changes: 65 additions & 0 deletions packages/specs/schema/src/components/operationMapper.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import {getStatusMessage} from "../constants/httpStatusMessages";
import {JsonOperation} from "../domain/JsonOperation";
import {JsonParameter} from "../domain/JsonParameter";
import {isParameterType, JsonParameterTypes} from "../domain/JsonParameterTypes";
import {JsonSchemaOptions} from "../interfaces/JsonSchemaOptions";
import {execMapper, registerJsonSchemaMapper} from "../registries/JsonSchemaMapperContainer";

function extractParameters(jsonOperation: JsonOperation, options: JsonSchemaOptions) {
return jsonOperation
.get("parameters")
.filter((parameter: JsonParameter) => isParameterType(parameter.get("in")))
.reduce(
(inputs: [any[], JsonParameter[]], parameter: JsonParameter) => {
const [parameters, bodyParameters] = inputs;

if ([JsonParameterTypes.BODY, JsonParameterTypes.FILES].includes(parameter.get("in"))) {
return [parameters, [...bodyParameters, parameter]];
}

return [[...parameters, parameter], bodyParameters];
},
[[], []]
);
}

export function operationMapper(jsonOperation: JsonOperation, {tags = [], defaultTags = [], ...options}: JsonSchemaOptions = {}) {
const {consumes, produces, ...operation} = execMapper("map", jsonOperation, {...options, ignore: ["parameters"]});

if (operation.security) {
operation.security = [].concat(operation.security);
}

if (jsonOperation.get("responses").size === 0) {
operation.responses = {
"200": {
description: getStatusMessage(200)
}
};
}

const parametersOptions = {
...options,
consumes: jsonOperation.get("consumes")?.length ? jsonOperation.get("consumes") : ["application/json"]
};

const [parameters, bodyParameters] = extractParameters(jsonOperation, parametersOptions);

operation.parameters = execMapper("operationInParameters", parameters, options);

if (bodyParameters.length) {
operation.requestBody = execMapper("operationRequestBody", bodyParameters, parametersOptions);
}

const operationTags = operation.tags?.length ? operation.tags : defaultTags;

if (operationTags.length) {
operation.tags = operationTags.map(({name}: any) => name);
}

tags.push(...operationTags);

return operation;
}

registerJsonSchemaMapper("operation", operationMapper);
11 changes: 11 additions & 0 deletions packages/specs/schema/src/components/operationMediaMapper.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import {JsonMedia} from "../domain/JsonMedia";
import {JsonSchemaOptions} from "../interfaces/JsonSchemaOptions";
import {execMapper, registerJsonSchemaMapper} from "../registries/JsonSchemaMapperContainer";

export function operationMediaMapper(jsonMedia: JsonMedia, options: JsonSchemaOptions) {
let groups = [...(jsonMedia.groups || [])];

return execMapper("map", jsonMedia, {...options, groups, groupsName: jsonMedia.groupsName});
}

registerJsonSchemaMapper("operationMedia", operationMediaMapper);
73 changes: 73 additions & 0 deletions packages/specs/schema/src/components/operationRequestBodyMapper.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import {JsonOperation} from "../domain/JsonOperation";
import {JsonParameter} from "../domain/JsonParameter";
import {isParameterType, JsonParameterTypes} from "../domain/JsonParameterTypes";
import {JsonRequestBody} from "../domain/JsonRequestBody";
import {JsonSchema} from "../domain/JsonSchema";
import {JsonSchemaOptions} from "../interfaces/JsonSchemaOptions";
import {execMapper, registerJsonSchemaMapper} from "../registries/JsonSchemaMapperContainer";

function buildSchemaFromBodyParameters(parameters: JsonParameter[], options: JsonSchemaOptions) {
let schema = new JsonSchema();
const props: any = {};
const refs: JsonSchema[] = [];
let propsLength = 0;

parameters.forEach((parameter) => {
const name = parameter.getName();

[...parameter.entries()]
.filter(([key]) => !["in", "name"].includes(key))
.forEach(([key, value]) => {
if (props[key] === undefined) {
props[key] = value;
}
});

const jsonParameter = execMapper("operationInParameter", parameter, options);

if (name) {
schema.addProperty(
name,
jsonParameter.schema || {
type: jsonParameter.type
}
);

if (parameter.get("required")) {
schema.addRequired(name);
}

propsLength++;
} else {
refs.push(jsonParameter);
}
});

if (!propsLength) {
if (refs.length === 1) {
return refs[0];
}
}

schema.type("object");

return {
schema: schema.toJSON(options),
required: false,
...props
};
}

export function operationRequestBodyMapper(bodyParameters: JsonParameter[], {consumes, ...options}: JsonSchemaOptions) {
const {schema, examples, in: _, ...props} = buildSchemaFromBodyParameters(bodyParameters, options);

const requestBody = new JsonRequestBody(props);

consumes.forEach((consume: string) => {
requestBody.addContent(consume, schema, examples);
});

return execMapper("map", requestBody, options);
}

registerJsonSchemaMapper("operationRequestBody", operationRequestBodyMapper);
Loading

0 comments on commit 5c15da0

Please sign in to comment.