Skip to content

Commit

Permalink
🐛 fix: fix schema required
Browse files Browse the repository at this point in the history
  • Loading branch information
arvinxx committed Dec 15, 2023
1 parent c726d58 commit 0308c5b
Show file tree
Hide file tree
Showing 4 changed files with 174 additions and 2 deletions.
27 changes: 25 additions & 2 deletions src/openapi/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ export class OpenAPIConvertor {
const parameters = this.mergeSchemas(...Object.values(parametersSchema));

if (requestBodySchema && Object.keys(requestBodySchema.properties).length > 0) {
console.log(requestBodySchema);
parameters.properties[OPENAPI_REQUEST_BODY_KEY] = requestBodySchema;
parameters.required?.push('_requestBody');
}
Expand Down Expand Up @@ -168,7 +167,7 @@ export class OpenAPIConvertor {
for (const [contentType, mediaType] of Object.entries(requestBody.content)) {
if (mediaType.schema) {
// 直接使用已解析的 Schema
const resolvedSchema = mediaType.schema;
const resolvedSchema = this.removeRequiredFields(mediaType.schema);

// 根据不同的 content-type,可以在这里添加特定的处理逻辑
switch (contentType) {
Expand Down Expand Up @@ -196,6 +195,30 @@ export class OpenAPIConvertor {
return requestBodySchema as PluginSchema;
}

private removeRequiredFields(schema: any): any {
if (schema && typeof schema === 'object') {
// 如果是对象类型,遍历它的每个属性
for (const key in schema) {
// eslint-disable-next-line no-prototype-builtins
if (schema.hasOwnProperty(key)) {
const value = schema[key];

// 如果属性是 required 并且值为 true,则删除该属性
if (key === 'required' && value === true) {
delete schema[key];
} else {
// 否则,如果属性是对象或数组,则递归处理
schema[key] = this.removeRequiredFields(value);
}
}
}
} else if (Array.isArray(schema)) {
// 如果是数组类型,遍历每个元素
return schema.map(this.removeRequiredFields.bind(this));
}
return schema;
}

private mergeSchemas(...schemas: any[]) {
// 初始化合并后的 Schema
const mergedSchema: PluginSchema = {
Expand Down
54 changes: 54 additions & 0 deletions tests/__snapshots__/openapi.test.ts.snap
Original file line number Diff line number Diff line change
@@ -1,5 +1,59 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html

exports[`OpenAPIConvertor > convertOpenAPIToPluginSchema > ChatWithPDF 1`] = `
[
{
"description": "Load a PDF document",
"name": "loadPdf",
"parameters": {
"properties": {
"_requestBody": {
"properties": {
"pdf_url": {
"description": "The temporary URL of the PDF document to load.",
"format": "uri",
"type": "string",
},
},
"required": [
"pdf_url",
],
"type": "object",
},
},
"type": "object",
},
},
{
"description": "Query a loaded PDF document",
"name": "queryPdf",
"parameters": {
"properties": {
"_requestBody": {
"properties": {
"pdf_url": {
"description": "The temporary URL of the PDF document that is already loaded.",
"format": "uri",
"type": "string",
},
"query": {
"description": "The query or question to ask based on the PDF document.",
"type": "string",
},
},
"required": [
"query",
"pdf_url",
],
"type": "object",
},
},
"type": "object",
},
},
]
`;

exports[`OpenAPIConvertor > convertOpenAPIToPluginSchema > can convert OpenAPI v2 MJ openAPI 1`] = `
[
{
Expand Down
87 changes: 87 additions & 0 deletions tests/fixtures/ChatWithPDF.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
{
"components": {
"schemas": {
"loadPdfRequest": {
"type": "object",
"required": ["pdf_url"],
"properties": {
"pdf_url": {
"type": "string",
"format": "uri",
"description": "The temporary URL of the PDF document to load.",
"required": true
}
}
},
"queryPdfRequest": {
"type": "object",
"required": ["query", "pdf_url"],
"properties": {
"query": {
"type": "string",
"description": "The query or question to ask based on the PDF document.",
"required": true
},
"pdf_url": {
"type": "string",
"format": "uri",
"description": "The temporary URL of the PDF document that is already loaded.",
"required": true
}
}
},
"queryPdfResponse": {
"type": "object",
"properties": {
"results": {
"type": "array",
"items": { "type": "string" },
"description": "The list of text chunks from the PDF document that are relevant to the user's query."
}
}
}
}
},
"info": {
"title": "ChatWithPDF",
"description": "A plugin that allows users to load and query PDF documents or Google Drive documents using ChatGPT. Users must first provide a PDF URL for processing. Once the PDF is loaded, users can query, analyze, or ask questions from that PDF name without needing to specify everytime. User must provide a PDF or Google Drive link that can be publically accessible, only documents can be loaded. The query will be able to extract relevant parts of the document to the users request. The load may take a while to process and if it does not work on the first try, try again, unless you get an error message back. User can only load documents that can be publically accessible on the internet. If they wish to use Google Docs they must first export it as a PDF, upload it to Google Drive then share a link that anybody can access via the link so we can download and process it. And if they wish to upload their document they can instead use service like [Upload Document](https://tmpfiles.org/).",
"version": "v3"
},
"openapi": "3.0.1",
"paths": {
"/pdf/load": {
"post": {
"operationId": "loadPdf",
"summary": "Load a PDF document",
"requestBody": {
"required": true,
"content": {
"application/json": { "schema": { "$ref": "#/components/schemas/loadPdfRequest" } }
}
},
"responses": { "200": { "description": "OK" } }
}
},
"/pdf/query": {
"post": {
"operationId": "queryPdf",
"summary": "Query a loaded PDF document",
"requestBody": {
"required": true,
"content": {
"application/json": { "schema": { "$ref": "#/components/schemas/queryPdfRequest" } }
}
},
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": { "schema": { "$ref": "#/components/schemas/queryPdfResponse" } }
}
}
}
}
}
},
"servers": [{ "url": "https://chatwithpdf.sdan.io" }]
}
8 changes: 8 additions & 0 deletions tests/openapi.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { OpenAPIConvertor } from '@lobehub/chat-plugin-sdk/openapi';
import { describe, expect, it } from 'vitest';

import ChatWithPDF from './fixtures/ChatWithPDF.json';
import OpenAPI_Auth_API_Key from './fixtures/OpenAPI_Auth_API_Key.json';
import OpenAPIV2 from './fixtures/OpenAPI_V2.json';
import openAPIV3 from './fixtures/OpenAPI_V3.json';
Expand Down Expand Up @@ -28,6 +29,13 @@ describe('OpenAPIConvertor', () => {

expect(plugins).toMatchSnapshot();
});

it('ChatWithPDF', async () => {
const convertor = new OpenAPIConvertor(ChatWithPDF);
const plugins = await convertor.convertOpenAPIToPluginSchema();

expect(plugins).toMatchSnapshot();
});
});

describe('convertAuthToSettingsSchema', () => {
Expand Down

0 comments on commit 0308c5b

Please sign in to comment.