Skip to content

Commit

Permalink
fix(schema): allow declaring many summary and description for one end…
Browse files Browse the repository at this point in the history
…point
  • Loading branch information
Romakita committed Dec 23, 2024
1 parent 474e2d8 commit 0b8aac1
Show file tree
Hide file tree
Showing 12 changed files with 182 additions and 49 deletions.
2 changes: 1 addition & 1 deletion packages/specs/schema/.barrelsby.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"directory": ["./src", "./src/components"],
"exclude": ["**/__mock__", "**/__mocks__", "**/*.spec.ts", "**/test", "**/*.benchmark.ts"],
"exclude": ["**/__mock__", "**/__mocks__", "**/__fixtures__", "**/*.spec.ts", "**/test", "**/*.benchmark.ts"],
"delete": true
}
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ function mapOperationInPathParameters(options: JsonSchemaOptions) {
return {
operation: {
...operation,
...operationPath.toJSON(options),
parameters,
operationId:
operation.operationId ||
Expand Down
9 changes: 8 additions & 1 deletion packages/specs/schema/src/decorators/operations/operation.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {OperationVerbs} from "../../constants/OperationVerbs.js";
import {DecoratorContext} from "../../domain/DecoratorContext.js";
import {JsonMethodStore} from "../../domain/JsonMethodStore.js";
import {JsonMethodPath, type JsonOperation} from "../../domain/JsonOperation.js";
import {mapOperationOptions} from "../../utils/mapOperationOptions.js";

export interface RouteChainedDecorators {
Expand Down Expand Up @@ -53,12 +54,15 @@ export interface RouteChainedDecorators {
class OperationDecoratorContext extends DecoratorContext<RouteChainedDecorators> {
readonly methods: string[] = ["name", "description", "summary", "method", "id", "use", "useAfter", "useBefore"];
protected declare entity: JsonMethodStore;
protected operationPath: JsonMethodPath;

protected beforeInit() {
const path: string = this.get("path");
const method: string = OperationVerbs[this.get("method") as OperationVerbs] || OperationVerbs.CUSTOM;

path && this.entity.operation.addOperationPath(method, path);
if (path) {
this.operationPath = this.entity.operation.addOperationPath(method, path);
}
}

protected onMapKey(key: string, value: any) {
Expand All @@ -68,10 +72,13 @@ class OperationDecoratorContext extends DecoratorContext<RouteChainedDecorators>
this.entity.operation.operationId(value);
return;
case "summary":
this.operationPath?.summary(value);
this.entity.operation.summary(value);
return;
case "description":
this.operationPath?.description(value);
this.entity.operation.description(value);

return;
case "use":
this.entity.use(value);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import "../../index.js";

import {OperationVerbs} from "../../constants/OperationVerbs.js";
import {inspectOperationsPaths} from "../../domain/__fixtures__/inspectOperationsPaths.js";
import {JsonEntityStore} from "../../domain/JsonEntityStore.js";
import {Publish} from "./publish.js";

Expand All @@ -15,7 +16,7 @@ describe("Publish", () => {
const endpoint = JsonEntityStore.fromMethod(Test, "test");

// THEN
expect([...endpoint.operation!.operationPaths.values()]).toEqual([
expect(inspectOperationsPaths(endpoint)).toEqual([
{
method: OperationVerbs.PUBLISH,
path: "event"
Expand Down
19 changes: 10 additions & 9 deletions packages/specs/schema/src/decorators/operations/route.spec.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import {inspectOperationsPaths} from "../../domain/__fixtures__/inspectOperationsPaths.js";
import {JsonEntityStore, OperationVerbs} from "../../index.js";
import {All, Delete, Get, Head, Options, Patch, Post, Put} from "./route.js";

Expand All @@ -13,7 +14,7 @@ describe("Route decorators", () => {
const endpoint = JsonEntityStore.fromMethod(Test, "test");

// THEN
expect([...endpoint.operation!.operationPaths.values()]).toEqual([
expect(inspectOperationsPaths(endpoint)).toEqual([
{
method: OperationVerbs.ALL,
path: "/"
Expand All @@ -34,7 +35,7 @@ describe("Route decorators", () => {
const endpoint = JsonEntityStore.fromMethod(Test, "test");

// THEN
expect([...endpoint.operation!.operationPaths.values()]).toEqual([
expect(inspectOperationsPaths(endpoint)).toEqual([
{
method: OperationVerbs.GET,
path: "/"
Expand All @@ -54,7 +55,7 @@ describe("Route decorators", () => {
const endpoint = JsonEntityStore.fromMethod(Test, "test");

// THEN
expect([...endpoint.operation!.operationPaths.values()]).toEqual([
expect(inspectOperationsPaths(endpoint)).toEqual([
{
method: OperationVerbs.GET,
path: "/"
Expand Down Expand Up @@ -91,7 +92,7 @@ describe("Route decorators", () => {
const endpoint = JsonEntityStore.fromMethod(Test, "test");

// THEN
expect([...endpoint.operation!.operationPaths.values()]).toEqual([
expect(inspectOperationsPaths(endpoint)).toEqual([
{
method: OperationVerbs.POST,
path: "/"
Expand All @@ -112,7 +113,7 @@ describe("Route decorators", () => {
const endpoint = JsonEntityStore.fromMethod(Test, "test");

// THEN
expect([...endpoint.operation!.operationPaths.values()]).toEqual([
expect(inspectOperationsPaths(endpoint)).toEqual([
{
method: OperationVerbs.PUT,
path: "/"
Expand All @@ -136,7 +137,7 @@ describe("Route decorators", () => {
const endpoint = JsonEntityStore.fromMethod(Test, "test");

// THEN
expect([...endpoint.operation!.operationPaths.values()]).toEqual([
expect(inspectOperationsPaths(endpoint)).toEqual([
{
method: OperationVerbs.DELETE,
path: "/"
Expand All @@ -157,7 +158,7 @@ describe("Route decorators", () => {
const endpoint = JsonEntityStore.fromMethod(Test, "test");

// THEN
expect([...endpoint.operation!.operationPaths.values()]).toEqual([
expect(inspectOperationsPaths(endpoint)).toEqual([
{
method: OperationVerbs.HEAD,
path: "/"
Expand All @@ -178,7 +179,7 @@ describe("Route decorators", () => {
const endpoint = JsonEntityStore.fromMethod(Test, "test");

// THEN
expect([...endpoint.operation!.operationPaths.values()]).toEqual([
expect(inspectOperationsPaths(endpoint)).toEqual([
{
method: OperationVerbs.PATCH,
path: "/"
Expand All @@ -199,7 +200,7 @@ describe("Route decorators", () => {
const endpoint = JsonEntityStore.fromMethod(Test, "test");

// THEN
expect([...endpoint.operation!.operationPaths.values()]).toEqual([
expect(inspectOperationsPaths(endpoint)).toEqual([
{
method: OperationVerbs.OPTIONS,
path: "/"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import "../../index.js";

import {OperationVerbs} from "../../constants/OperationVerbs.js";
import {inspectOperationsPaths} from "../../domain/__fixtures__/inspectOperationsPaths.js";
import {JsonEntityStore} from "../../domain/JsonEntityStore.js";
import {Publish} from "./publish.js";
import {Subscribe} from "./subscribe.js";
Expand All @@ -17,7 +18,7 @@ describe("Subscribe", () => {
const endpoint = JsonEntityStore.fromMethod(Test, "test");

// THEN
expect([...endpoint.operation!.operationPaths.values()]).toEqual([
expect(inspectOperationsPaths(endpoint)).toEqual([
{
method: OperationVerbs.SUBSCRIBE,
path: "event"
Expand Down
16 changes: 7 additions & 9 deletions packages/specs/schema/src/domain/JsonMethodStore.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {Property} from "../decorators/common/property.js";
import {In} from "../decorators/operations/in.js";
import {Returns} from "../decorators/operations/returns.js";
import {Get} from "../decorators/operations/route.js";
import {inspectOperationsPaths} from "./__fixtures__/inspectOperationsPaths.js";
import {JsonEntityStore} from "./JsonEntityStore.js";
import {EndpointMetadata, JsonMethodStore} from "./JsonMethodStore.js";
import {JsonOperation} from "./JsonOperation.js";
Expand Down Expand Up @@ -124,7 +125,7 @@ describe("JsonMethodStore", () => {
// THEN
expect(endpoint.middlewares).toHaveLength(1);

expect([...endpoint.operationPaths.values()]).toEqual([
expect(inspectOperationsPaths(endpoint)).toEqual([
{
method: OperationVerbs.GET,
path: "/"
Expand Down Expand Up @@ -263,14 +264,11 @@ describe("JsonMethodStore", () => {
expect(storeMethod?.parameters.length).toEqual(1);
expect(storeMethod?.params.length).toEqual(1);

expect([...storeMethod?.operationPaths.entries()]).toEqual([
[
"GET/",
{
method: "GET",
path: "/"
}
]
expect(inspectOperationsPaths(storeMethod as JsonMethodStore)).toEqual([
{
method: "GET",
path: "/"
}
]);
expect(storeMethod?.getResponseOptions(200)).toEqual({
groups: undefined,
Expand Down
34 changes: 23 additions & 11 deletions packages/specs/schema/src/domain/JsonOperation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,25 @@ import {JsonParameter} from "./JsonParameter.js";
import {JsonResponse} from "./JsonResponse.js";
import {JsonSchema} from "./JsonSchema.js";

export interface JsonMethodPath {
path: string | RegExp;
method: string;
export class JsonMethodPath extends JsonMap<any> {
constructor(
public method: string,
public path: string | RegExp
) {
super();
}

summary(summary: string): this {
super.set("summary", summary);

return this;
}

[key: string]: any;
description(description: string): this {
super.set("description", description);

return this;
}
}

export interface JsonOperationOptions extends OS3Operation<JsonSchema, JsonParameter, JsonMap<JsonResponse>> {
Expand All @@ -24,6 +38,7 @@ export class JsonOperation extends JsonMap<JsonOperationOptions> {
$kind: string = "operation";

readonly operationPaths: Map<string, JsonMethodPath> = new Map();

#status: number;
#redirection: boolean = false;

Expand Down Expand Up @@ -199,14 +214,11 @@ export class JsonOperation extends JsonMap<JsonOperationOptions> {
this.set("produces", produces);
}

addOperationPath(method: string, path: string | RegExp, options: any = {}) {
this.operationPaths.set(String(method) + String(path), {
...options,
method,
path
});
addOperationPath(method: string, path: string | RegExp) {
const operationPath = new JsonMethodPath(method, path);
this.operationPaths.set(String(method) + String(path), operationPath);

return this;
return operationPath;
}

getAllowedOperationPath(allowedVerbs?: string[]) {
Expand Down
27 changes: 11 additions & 16 deletions packages/specs/schema/src/domain/JsonOperationRoute.spec.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import {BodyParams} from "@tsed/platform-params";

import {OperationVerbs} from "../constants/OperationVerbs.js";
import {Name} from "../decorators/common/name.js";
import {Get} from "../decorators/operations/route.js";
import {JsonEntityStore} from "./JsonEntityStore.js";
import {JsonOperation} from "./JsonOperation.js";
import {JsonMethodPath, JsonOperation} from "./JsonOperation.js";
import {JsonOperationRoute} from "./JsonOperationRoute.js";

describe("JsonOperationRoute", () => {
Expand All @@ -17,14 +18,12 @@ describe("JsonOperationRoute", () => {
const operationRoute = new JsonOperationRoute({
token: Test,
endpoint,
operationPath: {method: "GET", path: "/"},
operationPath: new JsonMethodPath("GET", "/"),
basePath: "/base"
});

expect(operationRoute.operationPath).toEqual({
method: "GET",
path: "/"
});
expect(operationRoute.operationPath?.method).toEqual("GET");
expect(operationRoute.operationPath?.path).toEqual("/");
expect(operationRoute.method).toEqual("GET");
expect(operationRoute.path).toEqual("/");
expect(operationRoute.fullPath).toEqual("/base");
Expand All @@ -50,14 +49,12 @@ describe("JsonOperationRoute", () => {
const operationRoute = new JsonOperationRoute({
token: Test,
endpoint,
operationPath: {method: "GET", path: "/"},
operationPath: new JsonMethodPath(OperationVerbs.GET, "/"),
basePath: "/base"
});

expect(operationRoute.operationPath).toEqual({
method: "GET",
path: "/"
});
expect(operationRoute.operationPath?.method).toEqual("GET");
expect(operationRoute.operationPath?.path).toEqual("/");
expect(operationRoute.method).toEqual("GET");
expect(operationRoute.path).toEqual("/");
expect(operationRoute.fullPath).toEqual("/base");
Expand All @@ -82,14 +79,12 @@ describe("JsonOperationRoute", () => {
const operationRoute = new JsonOperationRoute({
token: Test,
endpoint,
operationPath: {method: "GET", path: "/"},
operationPath: new JsonMethodPath("GET", "/"),
basePath: "/base"
});

expect(operationRoute.operationPath).toEqual({
method: "GET",
path: "/"
});
expect(operationRoute.operationPath?.method).toEqual("GET");
expect(operationRoute.operationPath?.path).toEqual("/");
expect(operationRoute.method).toEqual("GET");
expect(operationRoute.path).toEqual("/");
expect(operationRoute.fullPath).toEqual("/base");
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import type {JsonMethodStore} from "../JsonMethodStore.js";

export function inspectOperationsPaths(endpoint: JsonMethodStore) {
return [...endpoint.operationPaths.values()].map(({method, path}) => ({
method,
path
}));
}
Loading

0 comments on commit 0b8aac1

Please sign in to comment.