From 9057be3e8aa9995a059579c4becb6f66175c5139 Mon Sep 17 00:00:00 2001 From: Roman Kalyakin Date: Thu, 25 Apr 2024 16:16:56 +0200 Subject: [PATCH] fixed openapi validator --- src/middleware/openApiValidator.ts | 15 +- src/models/generated/responses.ts | 158 +++++++++++++++++- src/models/generated/schemas.ts | 130 +++++++++++++- src/schema/responses/baseFind.json | 9 +- src/schema/responses/searchFind.json | 5 +- ...erFind.json => textReuseClustersFind.json} | 2 +- ...sterGet.json => textReuseClustersGet.json} | 0 7 files changed, 296 insertions(+), 23 deletions(-) rename src/schema/responses/{textReuseClusterFind.json => textReuseClustersFind.json} (88%) rename src/schema/responses/{textReuseClusterGet.json => textReuseClustersGet.json} (100%) diff --git a/src/middleware/openApiValidator.ts b/src/middleware/openApiValidator.ts index 95a9d578..500a11ad 100644 --- a/src/middleware/openApiValidator.ts +++ b/src/middleware/openApiValidator.ts @@ -4,15 +4,24 @@ import type { ImpressoApplication } from '../types' import type { Application } from '@feathersjs/express' import * as OpenApiValidator from 'express-openapi-validator' import fs from 'fs' +import { logger } from '../logger' -export default async (app: ImpressoApplication & Application) => { +export default (app: ImpressoApplication & Application) => { + init(app).catch(e => { + logger.error('Important: Failed to initialize OpenAPI validator middleware', e) + }) +} + +const init = async (app: ImpressoApplication & Application) => { const isPublicApi = app.get('isPublicApi') if (!isPublicApi) return if (!('docs' in app)) throw new Error('`docs` property not found in app object. Is swagger initialized?') + const spec = (app as any)['docs'] as unknown as OpenAPIV3.Document + const specCopy = spec //JSON.parse(JSON.stringify(spec)) - const dereferencedOpenApiSpec = await RefParser.dereference(spec, { + const dereferencedOpenApiSpec = await RefParser.bundle(specCopy, { resolve: { file: { /** @@ -27,7 +36,6 @@ export default async (app: ImpressoApplication & Application) => { }, }, }) - const middlewares = OpenApiValidator.middleware({ apiSpec: dereferencedOpenApiSpec as unknown as OpenAPIV3.Document, validateRequests: true, // (default) @@ -35,4 +43,5 @@ export default async (app: ImpressoApplication & Application) => { validateApiSpec: false, }) middlewares.forEach(middleware => app.use(middleware)) + logger.info('OpenAPI validator middleware loaded') } diff --git a/src/models/generated/responses.ts b/src/models/generated/responses.ts index d79d6f17..27038b46 100644 --- a/src/models/generated/responses.ts +++ b/src/models/generated/responses.ts @@ -3,6 +3,22 @@ */ export interface SearchFindResponse { data: any[]; + /** + * Additional information about the response. + */ + info: { [key: string]: any }; + /** + * The number of items returned in this response + */ + limit: number; + /** + * The number of items skipped in this response + */ + skip: number; + /** + * The total number of items matching the query + */ + total: number; } /** @@ -140,9 +156,6 @@ export interface User { username: string; } -/** - * Search find response (articles) - */ export interface BaseFindResponse { data: any[]; /** @@ -165,8 +178,6 @@ export interface BaseFindResponse { /** * Collectable Item find response - * - * Search find response (articles) */ export interface CollectableItemFindResponse { data: any[]; @@ -195,8 +206,6 @@ export interface BaseUser { /** * Collections find response - * - * Search find response (articles) */ export interface CollectionsFindResponse { data: any[]; @@ -245,6 +254,139 @@ export interface Task { task_id?: string; } +/** + * Response for the find newspapers endpoint. + */ +export interface FindNewspapersResponse { + data: any[]; +} + +/** + * A newspaper + */ +export interface NewspapersGet { + /** + * The acronym of the newspaper + */ + acronym: string; + /** + * The number of articles in the newspaper + */ + countArticles: number; + /** + * The number of issues in the newspaper + */ + countIssues: number; + /** + * The number of pages in the newspaper + */ + countPages: number; + /** + * The number of years of the newspaper available + */ + deltaYear: number; + /** + * Last available year of the newspaper articles + */ + endYear: string; + /** + * TODO + */ + fetched?: boolean; + /** + * First available issue of the newspaper + */ + firstIssue: NewspaperIssue; + /** + * TODO + */ + included: boolean; + /** + * The labels of the newspaper + */ + labels: string[]; + /** + * Language codes of the languages used in the newspaper + */ + languages: string[]; + /** + * Last available issue of the newspaper + */ + lastIssue: NewspaperIssue; + /** + * Title of the newspaper + */ + name: string; + /** + * TODO + */ + properties?: NewspaperProperty[]; + /** + * First available year of the newspaper articles + */ + startYear: string; + /** + * The unique identifier of the newspaper + */ + uid: string; +} + +/** + * First available issue of the newspaper + * + * Last available issue of the newspaper + */ +export interface NewspaperIssue { + /** + * TODO: list available options + */ + accessRights: string; + /** + * TODO + */ + cover: string; + /** + * The date of the issue + */ + date: Date; + /** + * TODO + */ + fresh: boolean; + /** + * The labels of the issue + */ + labels: string[]; + /** + * The unique identifier of the issue + */ + uid: string; + /** + * The year of the issue + */ + year: string; +} + +export interface NewspaperProperty { + /** + * Whether the value is a URL + */ + isUrl?: boolean; + /** + * The label of the property + */ + label: string; + /** + * The name of the property + */ + name: string; + /** + * The value of the property + */ + value: string; + [property: string]: any; +} + export interface FindTextReuseClustersResponse { clusters: GetTextReuseClusterResponse[]; info: Pagination; @@ -351,8 +493,6 @@ export interface Pagination { /** * Collections find response - * - * Search find response (articles) */ export interface TextReusePassageFindResponse { data: any[]; diff --git a/src/models/generated/schemas.ts b/src/models/generated/schemas.ts index 0dcbf58b..f36429ab 100644 --- a/src/models/generated/schemas.ts +++ b/src/models/generated/schemas.ts @@ -212,6 +212,132 @@ export enum Precision { Soft = "soft", } +/** + * A newspaper + */ +export interface Newspaper { + /** + * The acronym of the newspaper + */ + acronym: string; + /** + * The number of articles in the newspaper + */ + countArticles: number; + /** + * The number of issues in the newspaper + */ + countIssues: number; + /** + * The number of pages in the newspaper + */ + countPages: number; + /** + * The number of years of the newspaper available + */ + deltaYear: number; + /** + * Last available year of the newspaper articles + */ + endYear: string; + /** + * TODO + */ + fetched?: boolean; + /** + * First available issue of the newspaper + */ + firstIssue: NewspaperIssue; + /** + * TODO + */ + included: boolean; + /** + * The labels of the newspaper + */ + labels: string[]; + /** + * Language codes of the languages used in the newspaper + */ + languages: string[]; + /** + * Last available issue of the newspaper + */ + lastIssue: NewspaperIssue; + /** + * Title of the newspaper + */ + name: string; + /** + * TODO + */ + properties?: NewspaperProperty[]; + /** + * First available year of the newspaper articles + */ + startYear: string; + /** + * The unique identifier of the newspaper + */ + uid: string; +} + +/** + * First available issue of the newspaper + * + * Last available issue of the newspaper + */ +export interface NewspaperIssue { + /** + * TODO: list available options + */ + accessRights: string; + /** + * TODO + */ + cover: string; + /** + * The date of the issue + */ + date: Date; + /** + * TODO + */ + fresh: boolean; + /** + * The labels of the issue + */ + labels: string[]; + /** + * The unique identifier of the issue + */ + uid: string; + /** + * The year of the issue + */ + year: string; +} + +export interface NewspaperProperty { + /** + * Whether the value is a URL + */ + isUrl?: boolean; + /** + * The label of the property + */ + label: string; + /** + * The name of the property + */ + name: string; + /** + * The value of the property + */ + value: string; + [property: string]: any; +} + /** * Represents a cluster of text reuse passages */ @@ -317,7 +443,7 @@ export interface TextReusePassage { /** * Newspaper details */ - newspaper?: Newspaper; + newspaper?: NewspaperClass; offsetEnd: number; offsetStart: number; /** @@ -375,7 +501,7 @@ export interface Issue { /** * Newspaper details */ -export interface Newspaper { +export interface NewspaperClass { /** * ID of the newspaper */ diff --git a/src/schema/responses/baseFind.json b/src/schema/responses/baseFind.json index 96938e37..2da7941a 100644 --- a/src/schema/responses/baseFind.json +++ b/src/schema/responses/baseFind.json @@ -2,11 +2,10 @@ "$schema": "http://json-schema.org/draft-07/schema#", "type": "object", "title": "Base find response", - "additionalProperties": false, - "required": ["data", "limit", "skip", "total", "info"], "properties": { "data": { - "type": "array" + "type": "array", + "items": {} }, "limit": { "type": "integer", @@ -25,5 +24,7 @@ "description": "Additional information about the response.", "properties": {} } - } + }, + "required": ["data", "limit", "skip", "total", "info"], + "additionalProperties": false } diff --git a/src/schema/responses/searchFind.json b/src/schema/responses/searchFind.json index 709fdd8d..6cae2c55 100644 --- a/src/schema/responses/searchFind.json +++ b/src/schema/responses/searchFind.json @@ -1,12 +1,9 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "$ref": "baseFind.json", - "unevaluatedProperties": false, + "allOf": [{ "$ref": "baseFind.json" }], "type": "object", "title": "Search Find Response", "description": "Search find response (articles)", - "additionalProperties": false, - "required": ["data"], "properties": { "data": { "type": "array", diff --git a/src/schema/responses/textReuseClusterFind.json b/src/schema/responses/textReuseClustersFind.json similarity index 88% rename from src/schema/responses/textReuseClusterFind.json rename to src/schema/responses/textReuseClustersFind.json index c10601b2..84515b3d 100644 --- a/src/schema/responses/textReuseClusterFind.json +++ b/src/schema/responses/textReuseClustersFind.json @@ -7,7 +7,7 @@ "clusters": { "type": "array", "items": { - "$ref": "./textReuseClusterGet.json" + "$ref": "./textReuseClustersGet.json" } }, "info": { diff --git a/src/schema/responses/textReuseClusterGet.json b/src/schema/responses/textReuseClustersGet.json similarity index 100% rename from src/schema/responses/textReuseClusterGet.json rename to src/schema/responses/textReuseClustersGet.json