fix: swagger recursive type not working
This commit is contained in:
parent
ce22f77b32
commit
c1eaeb5c64
4 changed files with 114 additions and 57 deletions
|
|
@ -1,9 +1,10 @@
|
|||
import { Body, Controller, Post, Route, Security, SuccessResponse, Tags } from "tsoa";
|
||||
import HttpStatusCode from "../interfaces/http-status";
|
||||
import esClient from "../elasticsearch";
|
||||
import { Search, SearchInfo, SearchOperator } from "../interfaces/search";
|
||||
import { Search, SearchInfo, SearchOperator, SearchOptions } from "../interfaces/search";
|
||||
import { StorageFile } from "../interfaces/storage-fs";
|
||||
import { QueryDslQueryContainer } from "@elastic/elasticsearch/lib/api/types";
|
||||
import HttpError from "../interfaces/http-error";
|
||||
|
||||
const DEFAULT_INDEX = process.env.ELASTICSEARCH_INDEX;
|
||||
|
||||
|
|
@ -15,7 +16,26 @@ export class SearchController extends Controller {
|
|||
@Tags("Search")
|
||||
@Security("bearerAuth")
|
||||
@SuccessResponse(HttpStatusCode.OK, "สำเร็จ")
|
||||
public async searchFile(@Body() search: Search): Promise<StorageFile[]> {
|
||||
public async searchFile(
|
||||
@Body()
|
||||
body: {
|
||||
AND?: (
|
||||
| SearchInfo
|
||||
| {
|
||||
AND?: unknown;
|
||||
OR?: unknown;
|
||||
}
|
||||
)[];
|
||||
OR?: (
|
||||
| SearchInfo
|
||||
| {
|
||||
AND?: unknown;
|
||||
OR?: unknown;
|
||||
}
|
||||
)[];
|
||||
} & SearchOptions,
|
||||
): Promise<StorageFile[]> {
|
||||
const search = body as Search;
|
||||
const type = ["match", "match_phrase"] as const;
|
||||
|
||||
const searchMapCallback = (v: SearchInfo | SearchOperator): QueryDslQueryContainer => {
|
||||
|
|
@ -23,9 +43,16 @@ export class SearchController extends Controller {
|
|||
return { [type[search.exact || v.exact ? 1 : 0]]: { [v.field]: v.value } };
|
||||
}
|
||||
|
||||
return {
|
||||
bool: { must: v.AND?.map(searchMapCallback), should: v.OR?.map(searchMapCallback) },
|
||||
};
|
||||
if ("AND" in v || "OR" in v) {
|
||||
return {
|
||||
bool: { must: v.AND?.map(searchMapCallback), should: v.OR?.map(searchMapCallback) },
|
||||
};
|
||||
}
|
||||
|
||||
throw new HttpError(
|
||||
HttpStatusCode.UNPROCESSABLE_ENTITY,
|
||||
"ข้อมูลค้นหาไม่ถูกต้อง กรุณาตรวจสอบอีกครั้ง",
|
||||
);
|
||||
};
|
||||
|
||||
const result = await esClient.search<StorageFile & { attachment: Record<string, string> }>({
|
||||
|
|
|
|||
|
|
@ -1,5 +1,11 @@
|
|||
import { QueryDslQueryContainer } from "@elastic/elasticsearch/lib/api/types";
|
||||
|
||||
export interface SearchOptions {
|
||||
recursive?: boolean;
|
||||
path?: string[];
|
||||
exact?: boolean;
|
||||
}
|
||||
|
||||
export interface SearchInfo {
|
||||
field: string;
|
||||
value: string;
|
||||
|
|
@ -11,11 +17,7 @@ export interface SearchOperator {
|
|||
OR?: (SearchInfo | SearchOperator)[];
|
||||
}
|
||||
|
||||
export interface Search extends SearchOperator {
|
||||
recursive?: boolean;
|
||||
path?: string[];
|
||||
exact?: boolean;
|
||||
}
|
||||
export type Search = SearchOperator & SearchOptions;
|
||||
|
||||
export function mapCallback(exact: boolean) {
|
||||
const type = ["match", "match_phrase"] as const;
|
||||
|
|
|
|||
|
|
@ -45,14 +45,22 @@ const models: TsoaRoute.Models = {
|
|||
"additionalProperties": false,
|
||||
},
|
||||
// WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
|
||||
"Search": {
|
||||
"SearchInfo": {
|
||||
"dataType": "refObject",
|
||||
"properties": {
|
||||
"AND": {"dataType":"array","array":{"dataType":"nestedObjectLiteral","nestedProperties":{"exact":{"dataType":"boolean"},"value":{"dataType":"string","required":true},"field":{"dataType":"string","required":true}}}},
|
||||
"OR": {"dataType":"array","array":{"dataType":"nestedObjectLiteral","nestedProperties":{"exact":{"dataType":"boolean"},"value":{"dataType":"string","required":true},"field":{"dataType":"string","required":true}}}},
|
||||
"field": {"dataType":"string","required":true},
|
||||
"value": {"dataType":"string","required":true},
|
||||
"exact": {"dataType":"boolean"},
|
||||
},
|
||||
"additionalProperties": false,
|
||||
},
|
||||
// WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
|
||||
"SearchOptions": {
|
||||
"dataType": "refObject",
|
||||
"properties": {
|
||||
"recursive": {"dataType":"boolean"},
|
||||
"path": {"dataType":"array","array":{"dataType":"string"}},
|
||||
"exact": {"dataType":"boolean"},
|
||||
},
|
||||
"additionalProperties": false,
|
||||
},
|
||||
|
|
@ -177,7 +185,7 @@ export function RegisterRoutes(app: Router) {
|
|||
|
||||
function SearchController_searchFile(request: any, response: any, next: any) {
|
||||
const args = {
|
||||
search: {"in":"body","name":"search","required":true,"ref":"Search"},
|
||||
body: {"in":"body","name":"body","required":true,"dataType":"intersection","subSchemas":[{"dataType":"nestedObjectLiteral","nestedProperties":{"OR":{"dataType":"array","array":{"dataType":"union","subSchemas":[{"ref":"SearchInfo"},{"dataType":"nestedObjectLiteral","nestedProperties":{"OR":{"dataType":"any"},"AND":{"dataType":"any"}}}]}},"AND":{"dataType":"array","array":{"dataType":"union","subSchemas":[{"ref":"SearchInfo"},{"dataType":"nestedObjectLiteral","nestedProperties":{"OR":{"dataType":"any"},"AND":{"dataType":"any"}}}]}}}},{"ref":"SearchOptions"}]},
|
||||
};
|
||||
|
||||
// WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
|
||||
|
|
|
|||
|
|
@ -110,53 +110,27 @@
|
|||
"type": "object",
|
||||
"additionalProperties": false
|
||||
},
|
||||
"Search": {
|
||||
"SearchInfo": {
|
||||
"properties": {
|
||||
"AND": {
|
||||
"items": {
|
||||
"properties": {
|
||||
"exact": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"value": {
|
||||
"type": "string"
|
||||
},
|
||||
"field": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"value",
|
||||
"field"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"type": "array"
|
||||
"field": {
|
||||
"type": "string"
|
||||
},
|
||||
"OR": {
|
||||
"items": {
|
||||
"properties": {
|
||||
"exact": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"value": {
|
||||
"type": "string"
|
||||
},
|
||||
"field": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"value",
|
||||
"field"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"type": "array"
|
||||
"value": {
|
||||
"type": "string"
|
||||
},
|
||||
"exact": {
|
||||
"type": "boolean"
|
||||
},
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"field",
|
||||
"value"
|
||||
],
|
||||
"type": "object",
|
||||
"additionalProperties": false
|
||||
},
|
||||
"SearchOptions": {
|
||||
"properties": {
|
||||
"recursive": {
|
||||
"type": "boolean"
|
||||
},
|
||||
|
|
@ -165,6 +139,9 @@
|
|||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"exact": {
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
"type": "object",
|
||||
|
|
@ -617,7 +594,50 @@
|
|||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/Search"
|
||||
"allOf": [
|
||||
{
|
||||
"properties": {
|
||||
"OR": {
|
||||
"items": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/SearchInfo"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"OR": {},
|
||||
"AND": {}
|
||||
},
|
||||
"type": "object"
|
||||
}
|
||||
]
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"AND": {
|
||||
"items": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/SearchInfo"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"OR": {},
|
||||
"AND": {}
|
||||
},
|
||||
"type": "object"
|
||||
}
|
||||
]
|
||||
},
|
||||
"type": "array"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/SearchOptions"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue