From 5a0986930b5aad955fad88fa3ad46b93b7e80183 Mon Sep 17 00:00:00 2001 From: Luke Hagar Date: Sat, 27 Sep 2025 01:33:45 +0000 Subject: [PATCH] Refactor OpenAPI parsing logic to improve error handling and type safety. Update integration tests to validate handling of malformed JSON and YAML inputs, ensuring consistent detection of non-OpenAPI content. --- src/index.ts | 55 +++++++++++++++------------------------- test/integration.test.ts | 12 ++++++--- 2 files changed, 28 insertions(+), 39 deletions(-) diff --git a/src/index.ts b/src/index.ts index 56a49e2..6877b77 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,5 +1,5 @@ import * as yaml from 'js-yaml'; -import type{ AstPath, Doc, Parser, ParserOptions, Printer, SupportLanguage } from 'prettier'; +import type { AstPath, Doc, Parser, ParserOptions, Printer, SupportLanguage } from 'prettier'; import { getVendorExtensions } from './extensions/vendor-loader.js'; export type PrintFn = (path: AstPath) => Doc; @@ -35,9 +35,8 @@ import { // Type definitions for better type safety interface OpenAPINode { isOpenAPI: boolean; - content: any; - originalText: string; - format: 'json' | 'yaml'; + content?: any; + format?: 'json' | 'yaml'; } interface OpenAPIPluginOptions { @@ -48,10 +47,6 @@ interface OpenAPIPluginOptions { // Load vendor extensions const vendorExtensions = getVendorExtensions(); -// ============================================================================ -// UNIFIED PARSER FUNCTIONS -// ============================================================================ - /** * Unified parser that can handle both JSON and YAML OpenAPI files */ @@ -81,27 +76,25 @@ function parseOpenAPIFile(text: string, options?: any): OpenAPINode { let parsed: any; - switch (format) { - case 'yaml': - try { - parsed = yaml.load(text, { - schema: yaml.DEFAULT_SCHEMA, - onWarning: (warning) => { - // Handle YAML warnings if needed - console.warn('YAML parsing warning:', warning); + try { + switch (format) { + case 'yaml': + parsed = yaml.load(text, { + schema: yaml.DEFAULT_SCHEMA, + onWarning: (warning) => { + // Handle YAML warnings if needed + console.warn('YAML parsing warning:', warning); } }); - } catch (error) { - throw new Error(`Failed to parse OpenAPI YAML: ${error}`); - } - break; - case 'json': - try { + break; + case 'json': parsed = JSON.parse(text); - } catch (error) { - throw new Error(`Failed to parse OpenAPI JSON: ${error}`); - } - break; + break; + } + } catch (error) { + return { + isOpenAPI: false, + } } let isOpenAPI: boolean; @@ -111,9 +104,6 @@ function parseOpenAPIFile(text: string, options?: any): OpenAPINode { } catch (error) { return { isOpenAPI: false, - content: parsed, - originalText: text, - format: format, } } @@ -122,16 +112,11 @@ function parseOpenAPIFile(text: string, options?: any): OpenAPINode { return { isOpenAPI: true, content: parsed, - originalText: text, format: format, } case false: - default: return { isOpenAPI: false, - content: parsed, - originalText: text, - format: format, } } } @@ -272,7 +257,7 @@ export const parsers: Record = { }, astFormat: 'openapi-ast', locStart: (node: OpenAPINode) => 0, - locEnd: (node: OpenAPINode) => node.originalText?.length || 0, + locEnd: (node: OpenAPINode) => node.content?.length || 0, }, } diff --git a/test/integration.test.ts b/test/integration.test.ts index ae8d5ad..a9afbf0 100644 --- a/test/integration.test.ts +++ b/test/integration.test.ts @@ -457,7 +457,10 @@ describe('Integration Tests', () => { const malformedJson = '{"openapi": "3.0.0", "info": {'; // @ts-expect-error We are mocking things here - expect(() => parser?.parse(malformedJson, { filepath: 'test.json' })).toThrow(); + const result = parser?.parse(malformedJson, { filepath: 'test.json' }); + + expect(result).toBeDefined(); + expect(result?.isOpenAPI).toBeFalse(); }); it('should handle malformed YAML gracefully', () => { @@ -467,7 +470,10 @@ describe('Integration Tests', () => { const malformedYaml = 'openapi: 3.0.0\ninfo:\n title: Test\n version: 1.0.0\n invalid: ['; // @ts-expect-error We are mocking things here - expect(() => parser?.parse(malformedYaml, { filepath: 'test.yaml' })).toThrow(); + const result = parser?.parse(malformedYaml, { filepath: 'test.yaml' }); + + expect(result).toBeDefined(); + expect(result?.isOpenAPI).toBeFalse(); }); it('should handle non-OpenAPI content', () => { @@ -485,8 +491,6 @@ describe('Integration Tests', () => { const parsedData = parser?.parse(nonOpenAPI, { filepath: 'test.json' }) expect(parsedData).toBeDefined(); expect(parsedData?.isOpenAPI).toBeFalse(); - expect(parsedData?.content).toBeDefined(); - expect(parsedData?.content).toEqual(parsedJSON); }); });