mirror of
https://github.com/LukeHagar/prettier-plugin-openapi.git
synced 2025-12-06 12:47:47 +00:00
Update pretest script in package.json to use bun for building. Refactor sorting logic in index.ts for OpenAPI keys, enhancing clarity and performance. Clean up test files by removing unnecessary console logs and ensuring consistent formatting.
This commit is contained in:
@@ -38,7 +38,7 @@
|
||||
"scripts": {
|
||||
"build": "rollup -c && tsc --emitDeclarationOnly",
|
||||
"dev": "rollup -c --watch",
|
||||
"pretest": "rollup -c",
|
||||
"pretest": "bun run build",
|
||||
"test": "bun test",
|
||||
"test:coverage": "bun test --coverage",
|
||||
"test:watch": "bun test --watch",
|
||||
|
||||
58
src/index.ts
58
src/index.ts
@@ -300,10 +300,9 @@ function sortOpenAPIKeys(obj: any): any {
|
||||
const standardKeys = getStandardKeysForContext(contextKey);
|
||||
const customExtensions = vendorExtensions[contextKey] || {};
|
||||
|
||||
|
||||
const sortedKeys = Object.keys(obj).sort((a, b) => {
|
||||
// Use the unified sorting function
|
||||
return sortKeys(a, b, standardKeys, customExtensions);
|
||||
return sortKeys(a, b, standardKeys, customExtensions);;
|
||||
});
|
||||
|
||||
const sortedObj: any = {};
|
||||
@@ -515,39 +514,52 @@ function sortKeys(a: string, b: string, standardKeys: readonly string[], customE
|
||||
const aCustomPos = customExtensions[a];
|
||||
const bCustomPos = customExtensions[b];
|
||||
|
||||
// Handle custom extensions first
|
||||
// Get standard key positions
|
||||
const aStandardIndex = standardKeys.indexOf(a);
|
||||
const bStandardIndex = standardKeys.indexOf(b);
|
||||
|
||||
// Both are custom extensions
|
||||
if (aCustomPos !== undefined && bCustomPos !== undefined) {
|
||||
return aCustomPos - bCustomPos;
|
||||
}
|
||||
|
||||
if (aCustomPos !== undefined) {
|
||||
if (aCustomPos < standardKeys.length) {
|
||||
return -1; // Custom key should come before standard keys
|
||||
// Both are standard keys
|
||||
if (aStandardIndex !== -1 && bStandardIndex !== -1) {
|
||||
return aStandardIndex - bStandardIndex;
|
||||
}
|
||||
|
||||
// One is custom, one is standard
|
||||
if (aCustomPos !== undefined && bStandardIndex !== -1) {
|
||||
// Custom key should be positioned relative to standard keys
|
||||
if (aCustomPos < bStandardIndex) {
|
||||
return -1; // Custom key comes before this standard key
|
||||
} else if (aCustomPos > bStandardIndex) {
|
||||
return 1; // Custom key comes after this standard key
|
||||
} else {
|
||||
return -1; // Custom key comes before standard key at same position
|
||||
}
|
||||
}
|
||||
|
||||
if (bCustomPos !== undefined) {
|
||||
if (bCustomPos < standardKeys.length) {
|
||||
return 1; // Custom key should come before standard keys
|
||||
if (bCustomPos !== undefined && aStandardIndex !== -1) {
|
||||
// Custom key should be positioned relative to standard keys
|
||||
if (bCustomPos < aStandardIndex) {
|
||||
return 1; // Custom key comes before this standard key
|
||||
} else if (bCustomPos > aStandardIndex) {
|
||||
return -1; // Custom key comes after this standard key
|
||||
} else {
|
||||
return 1; // Standard key comes after custom key at same position
|
||||
}
|
||||
}
|
||||
|
||||
// Standard sorting
|
||||
const aIndex = standardKeys.indexOf(a);
|
||||
const bIndex = standardKeys.indexOf(b);
|
||||
// One is standard, one is unknown
|
||||
if (aStandardIndex !== -1) return -1; // Standard key comes first
|
||||
if (bStandardIndex !== -1) return 1; // Standard key comes first
|
||||
|
||||
if (aIndex !== -1 && bIndex !== -1) {
|
||||
return aIndex - bIndex;
|
||||
}
|
||||
// One is custom, one is unknown
|
||||
if (aCustomPos !== undefined) return -1; // Custom key comes before unknown
|
||||
if (bCustomPos !== undefined) return 1; // Custom key comes before unknown
|
||||
|
||||
if (aIndex !== -1) return -1;
|
||||
if (bIndex !== -1) return 1;
|
||||
|
||||
// Handle custom extensions after standard keys
|
||||
if (aCustomPos !== undefined) return -1;
|
||||
if (bCustomPos !== undefined) return 1;
|
||||
|
||||
// For unknown keys, sort alphabetically at the end
|
||||
// Both are unknown - sort alphabetically
|
||||
return a.localeCompare(b);
|
||||
}
|
||||
//#endregion
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { describe, expect, it } from 'bun:test';
|
||||
import {parsers, printers} from '../src/index';
|
||||
import { parsers, printers } from '../src/index';
|
||||
|
||||
describe('Custom Extensions Support', () => {
|
||||
it('should handle custom extensions in top-level keys', () => {
|
||||
@@ -110,7 +110,7 @@ describe('Custom Extensions Support', () => {
|
||||
}
|
||||
};
|
||||
|
||||
// @ts-expect-error We are mocking things here so we don't need to pass a print function
|
||||
// @ts-expect-error We are mocking things here so we don't need to pass a print function
|
||||
const result = printer?.print({ getNode: () => testData }, { tabWidth: 2 }, () => '');
|
||||
expect(result).toBeDefined();
|
||||
expect(result).toContain('x-custom-field');
|
||||
@@ -371,6 +371,45 @@ describe('Custom Extensions Support', () => {
|
||||
expect(anotherUnknownIndex).toBeLessThan(unknownFieldIndex);
|
||||
});
|
||||
|
||||
it('should handle specific extension placement', () => {
|
||||
const printer = printers?.['openapi-ast'];
|
||||
expect(printer).toBeDefined();
|
||||
|
||||
const testData = {
|
||||
isOpenAPI: true,
|
||||
format: 'yaml',
|
||||
content: {
|
||||
'info': { 'title': 'Test API', 'version': '1.0.0' },
|
||||
'openapi': '3.0.0',
|
||||
'x-tagGroups': 'value',
|
||||
'tags': 'value',
|
||||
'paths': {},
|
||||
'x-metadata': { 'custom': 'data' },
|
||||
}
|
||||
};
|
||||
|
||||
// @ts-expect-error We are mocking things here
|
||||
const result = printer?.print({ getNode: () => testData }, { tabWidth: 2 }, () => '');
|
||||
expect(result).toBeDefined();
|
||||
|
||||
if (!result) {
|
||||
throw new Error('Result is undefined');
|
||||
}
|
||||
|
||||
const resultString = result.toString();
|
||||
|
||||
// Standard keys first, then custom extensions, then unknown keys alphabetically
|
||||
const openapiIndex = resultString.indexOf('openapi');
|
||||
const infoIndex = resultString.indexOf('info');
|
||||
const pathsIndex = resultString.indexOf('paths');
|
||||
const xTagGroupsIndex = resultString.indexOf('x-tagGroups:');
|
||||
const tagsIndex = resultString.indexOf('tags:');
|
||||
|
||||
expect(openapiIndex).toBeLessThan(infoIndex);
|
||||
expect(infoIndex).toBeLessThan(pathsIndex);
|
||||
expect(tagsIndex).toBeLessThan(xTagGroupsIndex);
|
||||
});
|
||||
|
||||
it('should handle mixed custom extensions and unknown keys', () => {
|
||||
const printer = printers?.['openapi-ast'];
|
||||
expect(printer).toBeDefined();
|
||||
|
||||
@@ -140,8 +140,6 @@ describe('Key Ordering Tests', () => {
|
||||
throw new Error('Result is undefined');
|
||||
}
|
||||
|
||||
console.log('result', result);
|
||||
|
||||
const resultString = result.toString();
|
||||
|
||||
const testIndex = resultString.indexOf('test"');
|
||||
@@ -198,7 +196,6 @@ describe('Key Ordering Tests', () => {
|
||||
|
||||
// @ts-expect-error We are mocking things here so we don't need to pass a print function
|
||||
const result = printer?.print({ getNode: () => testData }, { tabWidth: 2 });
|
||||
console.log('result', result);
|
||||
expect(result).toBeDefined();
|
||||
|
||||
if (!result) {
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { describe, expect, it } from 'bun:test';
|
||||
import plugin from '../dist/index.js';
|
||||
import { parsers, printers } from '../src/index.js';
|
||||
|
||||
describe('Prettier OpenAPI Plugin', () => {
|
||||
it('should format OpenAPI JSON files', () => {
|
||||
const parser = plugin.parsers?.['openapi-parser'];
|
||||
const printer = plugin.printers?.['openapi-ast'];
|
||||
const parser = parsers?.['openapi-parser'];
|
||||
const printer = printers?.['openapi-ast'];
|
||||
|
||||
expect(parser).toBeDefined();
|
||||
expect(printer).toBeDefined();
|
||||
@@ -59,8 +59,8 @@ describe('Prettier OpenAPI Plugin', () => {
|
||||
});
|
||||
|
||||
it('should format OpenAPI YAML files', () => {
|
||||
const parser = plugin.parsers?.['openapi-parser'];
|
||||
const printer = plugin.printers?.['openapi-ast'];
|
||||
const parser = parsers?.['openapi-parser'];
|
||||
const printer = printers?.['openapi-ast'];
|
||||
|
||||
expect(parser).toBeDefined();
|
||||
expect(printer).toBeDefined();
|
||||
@@ -114,8 +114,8 @@ openapi: 3.0.0`;
|
||||
});
|
||||
|
||||
it('should format Swagger 2.0 JSON files', () => {
|
||||
const parser = plugin.parsers?.['openapi-parser'];
|
||||
const printer = plugin.printers?.['openapi-ast'];
|
||||
const parser = parsers?.['openapi-parser'];
|
||||
const printer = printers?.['openapi-ast'];
|
||||
|
||||
expect(parser).toBeDefined();
|
||||
expect(printer).toBeDefined();
|
||||
@@ -181,8 +181,8 @@ openapi: 3.0.0`;
|
||||
describe('Key Ordering Tests', () => {
|
||||
describe('Top-level key ordering', () => {
|
||||
it('should sort OpenAPI 3.0+ keys correctly', () => {
|
||||
const parser = plugin.parsers?.['openapi-parser'];
|
||||
const printer = plugin.printers?.['openapi-ast'];
|
||||
const parser = parsers?.['openapi-parser'];
|
||||
const printer = printers?.['openapi-ast'];
|
||||
|
||||
expect(parser).toBeDefined();
|
||||
expect(printer).toBeDefined();
|
||||
@@ -233,8 +233,8 @@ describe('Key Ordering Tests', () => {
|
||||
});
|
||||
|
||||
it('should sort Swagger 2.0 keys correctly', () => {
|
||||
const parser = plugin.parsers?.['openapi-parser'];
|
||||
const printer = plugin.printers?.['openapi-ast'];
|
||||
const parser = parsers?.['openapi-parser'];
|
||||
const printer = printers?.['openapi-ast'];
|
||||
|
||||
expect(parser).toBeDefined();
|
||||
expect(printer).toBeDefined();
|
||||
|
||||
@@ -175,7 +175,6 @@ describe('Simple Key Ordering Tests', () => {
|
||||
|
||||
// @ts-expect-error We are mocking things here
|
||||
const result = printer?.print({ getNode: () => testData }, { tabWidth: 2 }, () => '');
|
||||
console.log('result', result);
|
||||
expect(result).toBeDefined();
|
||||
|
||||
if (!result) {
|
||||
|
||||
Reference in New Issue
Block a user