mirror of
https://github.com/LukeHagar/prettier-plugin-openapi.git
synced 2025-12-06 04:21:03 +00:00
Update package.json and bun.lock to include Rollup plugins, modify build scripts for Rollup integration, and enhance TypeScript configuration for improved module handling. Introduce rollup.config.js for bundling configurations and refactor parser and printer references in tests to align with new structure.
This commit is contained in:
103
bun.lock
103
bun.lock
@@ -9,9 +9,14 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@biomejs/biome": "^2.2.4",
|
||||
"@rollup/plugin-alias": "^5.1.1",
|
||||
"@rollup/plugin-commonjs": "^28.0.6",
|
||||
"@rollup/plugin-node-resolve": "^16.0.1",
|
||||
"@types/bun": "latest",
|
||||
"@types/node": "^20.0.0",
|
||||
"prettier": "^3.0.0",
|
||||
"rollup": "^4.52.2",
|
||||
"rollup-plugin-typescript": "^1.0.1",
|
||||
"typescript": "^5.0.0",
|
||||
},
|
||||
"peerDependencies": {
|
||||
@@ -38,30 +43,128 @@
|
||||
|
||||
"@biomejs/cli-win32-x64": ["@biomejs/cli-win32-x64@2.2.4", "", { "os": "win32", "cpu": "x64" }, "sha512-3Y4V4zVRarVh/B/eSHczR4LYoSVyv3Dfuvm3cWs5w/HScccS0+Wt/lHOcDTRYeHjQmMYVC3rIRWqyN2EI52+zg=="],
|
||||
|
||||
"@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.5", "", {}, "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og=="],
|
||||
|
||||
"@rollup/plugin-alias": ["@rollup/plugin-alias@5.1.1", "", { "peerDependencies": { "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" }, "optionalPeers": ["rollup"] }, "sha512-PR9zDb+rOzkRb2VD+EuKB7UC41vU5DIwZ5qqCpk0KJudcWAyi8rvYOhS7+L5aZCspw1stTViLgN5v6FF1p5cgQ=="],
|
||||
|
||||
"@rollup/plugin-commonjs": ["@rollup/plugin-commonjs@28.0.6", "", { "dependencies": { "@rollup/pluginutils": "^5.0.1", "commondir": "^1.0.1", "estree-walker": "^2.0.2", "fdir": "^6.2.0", "is-reference": "1.2.1", "magic-string": "^0.30.3", "picomatch": "^4.0.2" }, "peerDependencies": { "rollup": "^2.68.0||^3.0.0||^4.0.0" }, "optionalPeers": ["rollup"] }, "sha512-XSQB1K7FUU5QP+3lOQmVCE3I0FcbbNvmNT4VJSj93iUjayaARrTQeoRdiYQoftAJBLrR9t2agwAd3ekaTgHNlw=="],
|
||||
|
||||
"@rollup/plugin-node-resolve": ["@rollup/plugin-node-resolve@16.0.1", "", { "dependencies": { "@rollup/pluginutils": "^5.0.1", "@types/resolve": "1.20.2", "deepmerge": "^4.2.2", "is-module": "^1.0.0", "resolve": "^1.22.1" }, "peerDependencies": { "rollup": "^2.78.0||^3.0.0||^4.0.0" }, "optionalPeers": ["rollup"] }, "sha512-tk5YCxJWIG81umIvNkSod2qK5KyQW19qcBF/B78n1bjtOON6gzKoVeSzAE8yHCZEDmqkHKkxplExA8KzdJLJpA=="],
|
||||
|
||||
"@rollup/pluginutils": ["@rollup/pluginutils@5.3.0", "", { "dependencies": { "@types/estree": "^1.0.0", "estree-walker": "^2.0.2", "picomatch": "^4.0.2" }, "peerDependencies": { "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" }, "optionalPeers": ["rollup"] }, "sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q=="],
|
||||
|
||||
"@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.52.2", "", { "os": "android", "cpu": "arm" }, "sha512-o3pcKzJgSGt4d74lSZ+OCnHwkKBeAbFDmbEm5gg70eA8VkyCuC/zV9TwBnmw6VjDlRdF4Pshfb+WE9E6XY1PoQ=="],
|
||||
|
||||
"@rollup/rollup-android-arm64": ["@rollup/rollup-android-arm64@4.52.2", "", { "os": "android", "cpu": "arm64" }, "sha512-cqFSWO5tX2vhC9hJTK8WAiPIm4Q8q/cU8j2HQA0L3E1uXvBYbOZMhE2oFL8n2pKB5sOCHY6bBuHaRwG7TkfJyw=="],
|
||||
|
||||
"@rollup/rollup-darwin-arm64": ["@rollup/rollup-darwin-arm64@4.52.2", "", { "os": "darwin", "cpu": "arm64" }, "sha512-vngduywkkv8Fkh3wIZf5nFPXzWsNsVu1kvtLETWxTFf/5opZmflgVSeLgdHR56RQh71xhPhWoOkEBvbehwTlVA=="],
|
||||
|
||||
"@rollup/rollup-darwin-x64": ["@rollup/rollup-darwin-x64@4.52.2", "", { "os": "darwin", "cpu": "x64" }, "sha512-h11KikYrUCYTrDj6h939hhMNlqU2fo/X4NB0OZcys3fya49o1hmFaczAiJWVAFgrM1NCP6RrO7lQKeVYSKBPSQ=="],
|
||||
|
||||
"@rollup/rollup-freebsd-arm64": ["@rollup/rollup-freebsd-arm64@4.52.2", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-/eg4CI61ZUkLXxMHyVlmlGrSQZ34xqWlZNW43IAU4RmdzWEx0mQJ2mN/Cx4IHLVZFL6UBGAh+/GXhgvGb+nVxw=="],
|
||||
|
||||
"@rollup/rollup-freebsd-x64": ["@rollup/rollup-freebsd-x64@4.52.2", "", { "os": "freebsd", "cpu": "x64" }, "sha512-QOWgFH5X9+p+S1NAfOqc0z8qEpJIoUHf7OWjNUGOeW18Mx22lAUOiA9b6r2/vpzLdfxi/f+VWsYjUOMCcYh0Ng=="],
|
||||
|
||||
"@rollup/rollup-linux-arm-gnueabihf": ["@rollup/rollup-linux-arm-gnueabihf@4.52.2", "", { "os": "linux", "cpu": "arm" }, "sha512-kDWSPafToDd8LcBYd1t5jw7bD5Ojcu12S3uT372e5HKPzQt532vW+rGFFOaiR0opxePyUkHrwz8iWYEyH1IIQA=="],
|
||||
|
||||
"@rollup/rollup-linux-arm-musleabihf": ["@rollup/rollup-linux-arm-musleabihf@4.52.2", "", { "os": "linux", "cpu": "arm" }, "sha512-gKm7Mk9wCv6/rkzwCiUC4KnevYhlf8ztBrDRT9g/u//1fZLapSRc+eDZj2Eu2wpJ+0RzUKgtNijnVIB4ZxyL+w=="],
|
||||
|
||||
"@rollup/rollup-linux-arm64-gnu": ["@rollup/rollup-linux-arm64-gnu@4.52.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-66lA8vnj5mB/rtDNwPgrrKUOtCLVQypkyDa2gMfOefXK6rcZAxKLO9Fy3GkW8VkPnENv9hBkNOFfGLf6rNKGUg=="],
|
||||
|
||||
"@rollup/rollup-linux-arm64-musl": ["@rollup/rollup-linux-arm64-musl@4.52.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-s+OPucLNdJHvuZHuIz2WwncJ+SfWHFEmlC5nKMUgAelUeBUnlB4wt7rXWiyG4Zn07uY2Dd+SGyVa9oyLkVGOjA=="],
|
||||
|
||||
"@rollup/rollup-linux-loong64-gnu": ["@rollup/rollup-linux-loong64-gnu@4.52.2", "", { "os": "linux", "cpu": "none" }, "sha512-8wTRM3+gVMDLLDdaT6tKmOE3lJyRy9NpJUS/ZRWmLCmOPIJhVyXwjBo+XbrrwtV33Em1/eCTd5TuGJm4+DmYjw=="],
|
||||
|
||||
"@rollup/rollup-linux-ppc64-gnu": ["@rollup/rollup-linux-ppc64-gnu@4.52.2", "", { "os": "linux", "cpu": "ppc64" }, "sha512-6yqEfgJ1anIeuP2P/zhtfBlDpXUb80t8DpbYwXQ3bQd95JMvUaqiX+fKqYqUwZXqdJDd8xdilNtsHM2N0cFm6A=="],
|
||||
|
||||
"@rollup/rollup-linux-riscv64-gnu": ["@rollup/rollup-linux-riscv64-gnu@4.52.2", "", { "os": "linux", "cpu": "none" }, "sha512-sshYUiYVSEI2B6dp4jMncwxbrUqRdNApF2c3bhtLAU0qA8Lrri0p0NauOsTWh3yCCCDyBOjESHMExonp7Nzc0w=="],
|
||||
|
||||
"@rollup/rollup-linux-riscv64-musl": ["@rollup/rollup-linux-riscv64-musl@4.52.2", "", { "os": "linux", "cpu": "none" }, "sha512-duBLgd+3pqC4MMwBrKkFxaZerUxZcYApQVC5SdbF5/e/589GwVvlRUnyqMFbM8iUSb1BaoX/3fRL7hB9m2Pj8Q=="],
|
||||
|
||||
"@rollup/rollup-linux-s390x-gnu": ["@rollup/rollup-linux-s390x-gnu@4.52.2", "", { "os": "linux", "cpu": "s390x" }, "sha512-tzhYJJidDUVGMgVyE+PmxENPHlvvqm1KILjjZhB8/xHYqAGeizh3GBGf9u6WdJpZrz1aCpIIHG0LgJgH9rVjHQ=="],
|
||||
|
||||
"@rollup/rollup-linux-x64-gnu": ["@rollup/rollup-linux-x64-gnu@4.52.2", "", { "os": "linux", "cpu": "x64" }, "sha512-opH8GSUuVcCSSyHHcl5hELrmnk4waZoVpgn/4FDao9iyE4WpQhyWJ5ryl5M3ocp4qkRuHfyXnGqg8M9oKCEKRA=="],
|
||||
|
||||
"@rollup/rollup-linux-x64-musl": ["@rollup/rollup-linux-x64-musl@4.52.2", "", { "os": "linux", "cpu": "x64" }, "sha512-LSeBHnGli1pPKVJ79ZVJgeZWWZXkEe/5o8kcn23M8eMKCUANejchJbF/JqzM4RRjOJfNRhKJk8FuqL1GKjF5oQ=="],
|
||||
|
||||
"@rollup/rollup-openharmony-arm64": ["@rollup/rollup-openharmony-arm64@4.52.2", "", { "os": "none", "cpu": "arm64" }, "sha512-uPj7MQ6/s+/GOpolavm6BPo+6CbhbKYyZHUDvZ/SmJM7pfDBgdGisFX3bY/CBDMg2ZO4utfhlApkSfZ92yXw7Q=="],
|
||||
|
||||
"@rollup/rollup-win32-arm64-msvc": ["@rollup/rollup-win32-arm64-msvc@4.52.2", "", { "os": "win32", "cpu": "arm64" }, "sha512-Z9MUCrSgIaUeeHAiNkm3cQyst2UhzjPraR3gYYfOjAuZI7tcFRTOD+4cHLPoS/3qinchth+V56vtqz1Tv+6KPA=="],
|
||||
|
||||
"@rollup/rollup-win32-ia32-msvc": ["@rollup/rollup-win32-ia32-msvc@4.52.2", "", { "os": "win32", "cpu": "ia32" }, "sha512-+GnYBmpjldD3XQd+HMejo+0gJGwYIOfFeoBQv32xF/RUIvccUz20/V6Otdv+57NE70D5pa8W/jVGDoGq0oON4A=="],
|
||||
|
||||
"@rollup/rollup-win32-x64-gnu": ["@rollup/rollup-win32-x64-gnu@4.52.2", "", { "os": "win32", "cpu": "x64" }, "sha512-ApXFKluSB6kDQkAqZOKXBjiaqdF1BlKi+/eqnYe9Ee7U2K3pUDKsIyr8EYm/QDHTJIM+4X+lI0gJc3TTRhd+dA=="],
|
||||
|
||||
"@rollup/rollup-win32-x64-msvc": ["@rollup/rollup-win32-x64-msvc@4.52.2", "", { "os": "win32", "cpu": "x64" }, "sha512-ARz+Bs8kY6FtitYM96PqPEVvPXqEZmPZsSkXvyX19YzDqkCaIlhCieLLMI5hxO9SRZ2XtCtm8wxhy0iJ2jxNfw=="],
|
||||
|
||||
"@types/bun": ["@types/bun@1.2.22", "", { "dependencies": { "bun-types": "1.2.22" } }, "sha512-5A/KrKos2ZcN0c6ljRSOa1fYIyCKhZfIVYeuyb4snnvomnpFqC0tTsEkdqNxbAgExV384OETQ//WAjl3XbYqQA=="],
|
||||
|
||||
"@types/estree": ["@types/estree@1.0.8", "", {}, "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w=="],
|
||||
|
||||
"@types/js-yaml": ["@types/js-yaml@4.0.9", "", {}, "sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg=="],
|
||||
|
||||
"@types/node": ["@types/node@20.19.17", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-gfehUI8N1z92kygssiuWvLiwcbOB3IRktR6hTDgJlXMYh5OvkPSRmgfoBUmfZt+vhwJtX7v1Yw4KvvAf7c5QKQ=="],
|
||||
|
||||
"@types/react": ["@types/react@19.1.13", "", { "dependencies": { "csstype": "^3.0.2" } }, "sha512-hHkbU/eoO3EG5/MZkuFSKmYqPbSVk5byPFa3e7y/8TybHiLMACgI8seVYlicwk7H5K/rI2px9xrQp/C+AUDTiQ=="],
|
||||
|
||||
"@types/resolve": ["@types/resolve@1.20.2", "", {}, "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q=="],
|
||||
|
||||
"argparse": ["argparse@2.0.1", "", {}, "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="],
|
||||
|
||||
"bun-types": ["bun-types@1.2.22", "", { "dependencies": { "@types/node": "*" }, "peerDependencies": { "@types/react": "^19" } }, "sha512-hwaAu8tct/Zn6Zft4U9BsZcXkYomzpHJX28ofvx7k0Zz2HNz54n1n+tDgxoWFGB4PcFvJXJQloPhaV2eP3Q6EA=="],
|
||||
|
||||
"commondir": ["commondir@1.0.1", "", {}, "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg=="],
|
||||
|
||||
"csstype": ["csstype@3.1.3", "", {}, "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="],
|
||||
|
||||
"deepmerge": ["deepmerge@4.3.1", "", {}, "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A=="],
|
||||
|
||||
"estree-walker": ["estree-walker@2.0.2", "", {}, "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="],
|
||||
|
||||
"fdir": ["fdir@6.5.0", "", { "peerDependencies": { "picomatch": "^3 || ^4" }, "optionalPeers": ["picomatch"] }, "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg=="],
|
||||
|
||||
"fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="],
|
||||
|
||||
"function-bind": ["function-bind@1.1.2", "", {}, "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="],
|
||||
|
||||
"hasown": ["hasown@2.0.2", "", { "dependencies": { "function-bind": "^1.1.2" } }, "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ=="],
|
||||
|
||||
"is-core-module": ["is-core-module@2.16.1", "", { "dependencies": { "hasown": "^2.0.2" } }, "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w=="],
|
||||
|
||||
"is-module": ["is-module@1.0.0", "", {}, "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g=="],
|
||||
|
||||
"is-reference": ["is-reference@1.2.1", "", { "dependencies": { "@types/estree": "*" } }, "sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ=="],
|
||||
|
||||
"js-yaml": ["js-yaml@4.1.0", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA=="],
|
||||
|
||||
"magic-string": ["magic-string@0.30.19", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "sha512-2N21sPY9Ws53PZvsEpVtNuSW+ScYbQdp4b9qUaL+9QkHUrGFKo56Lg9Emg5s9V/qrtNBmiR01sYhUOwu3H+VOw=="],
|
||||
|
||||
"path-parse": ["path-parse@1.0.7", "", {}, "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="],
|
||||
|
||||
"picomatch": ["picomatch@4.0.3", "", {}, "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q=="],
|
||||
|
||||
"prettier": ["prettier@3.6.2", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ=="],
|
||||
|
||||
"resolve": ["resolve@1.22.10", "", { "dependencies": { "is-core-module": "^2.16.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" } }, "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w=="],
|
||||
|
||||
"rollup": ["rollup@4.52.2", "", { "dependencies": { "@types/estree": "1.0.8" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.52.2", "@rollup/rollup-android-arm64": "4.52.2", "@rollup/rollup-darwin-arm64": "4.52.2", "@rollup/rollup-darwin-x64": "4.52.2", "@rollup/rollup-freebsd-arm64": "4.52.2", "@rollup/rollup-freebsd-x64": "4.52.2", "@rollup/rollup-linux-arm-gnueabihf": "4.52.2", "@rollup/rollup-linux-arm-musleabihf": "4.52.2", "@rollup/rollup-linux-arm64-gnu": "4.52.2", "@rollup/rollup-linux-arm64-musl": "4.52.2", "@rollup/rollup-linux-loong64-gnu": "4.52.2", "@rollup/rollup-linux-ppc64-gnu": "4.52.2", "@rollup/rollup-linux-riscv64-gnu": "4.52.2", "@rollup/rollup-linux-riscv64-musl": "4.52.2", "@rollup/rollup-linux-s390x-gnu": "4.52.2", "@rollup/rollup-linux-x64-gnu": "4.52.2", "@rollup/rollup-linux-x64-musl": "4.52.2", "@rollup/rollup-openharmony-arm64": "4.52.2", "@rollup/rollup-win32-arm64-msvc": "4.52.2", "@rollup/rollup-win32-ia32-msvc": "4.52.2", "@rollup/rollup-win32-x64-gnu": "4.52.2", "@rollup/rollup-win32-x64-msvc": "4.52.2", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-I25/2QgoROE1vYV+NQ1En9T9UFB9Cmfm2CJ83zZOlaDpvz29wGQSZXWKw7MiNXau7wYgB/T9fVIdIuEQ+KbiiA=="],
|
||||
|
||||
"rollup-plugin-typescript": ["rollup-plugin-typescript@1.0.1", "", { "dependencies": { "resolve": "^1.10.0", "rollup-pluginutils": "^2.5.0" }, "peerDependencies": { "tslib": "*", "typescript": ">=2.1.0" } }, "sha512-rwJDNn9jv/NsKZuyBb/h0jsclP4CJ58qbvZt2Q9zDIGILF2LtdtvCqMOL+Gq9IVq5MTrTlHZNrn8h7VjQgd8tw=="],
|
||||
|
||||
"rollup-pluginutils": ["rollup-pluginutils@2.8.2", "", { "dependencies": { "estree-walker": "^0.6.1" } }, "sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ=="],
|
||||
|
||||
"supports-preserve-symlinks-flag": ["supports-preserve-symlinks-flag@1.0.0", "", {}, "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w=="],
|
||||
|
||||
"tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
|
||||
|
||||
"typescript": ["typescript@5.9.2", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A=="],
|
||||
|
||||
"undici-types": ["undici-types@6.21.0", "", {}, "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ=="],
|
||||
|
||||
"bun-types/@types/node": ["@types/node@24.5.2", "", { "dependencies": { "undici-types": "~7.12.0" } }, "sha512-FYxk1I7wPv3K2XBaoyH2cTnocQEu8AOZ60hPbsyukMPLv5/5qr7V1i8PLHdl6Zf87I+xZXFvPCXYjiTFq+YSDQ=="],
|
||||
|
||||
"rollup-pluginutils/estree-walker": ["estree-walker@0.6.1", "", {}, "sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w=="],
|
||||
|
||||
"bun-types/@types/node/undici-types": ["undici-types@7.12.0", "", {}, "sha512-goOacqME2GYyOZZfb5Lgtu+1IDmAlAEu5xnD3+xTzS10hT0vzpf0SPjkXwAw9Jm+4n/mQGDP3LO8CPbYROeBfQ=="],
|
||||
}
|
||||
}
|
||||
|
||||
33
package.json
33
package.json
@@ -9,13 +9,22 @@
|
||||
},
|
||||
"license": "MIT",
|
||||
"main": "dist/index.js",
|
||||
"module": "dist/index.js",
|
||||
"type": "module",
|
||||
"files": [
|
||||
"dist",
|
||||
"README.md",
|
||||
"LICENSE"
|
||||
"dist/index.js",
|
||||
"dist/index.js.map",
|
||||
"dist/browser.js",
|
||||
"dist/index.d.ts"
|
||||
],
|
||||
"types": "./dist/index.d.ts",
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./dist/index.d.ts",
|
||||
"default": "./dist/index.js"
|
||||
},
|
||||
"./browser": "./dist/browser.js",
|
||||
"./package.json": "./package.json"
|
||||
},
|
||||
"type": "module",
|
||||
"engines": {
|
||||
"node": ">=18.0.0"
|
||||
},
|
||||
@@ -28,16 +37,17 @@
|
||||
},
|
||||
"homepage": "https://github.com/lukehagar/prettier-plugin-openapi#readme",
|
||||
"scripts": {
|
||||
"build": "tsc",
|
||||
"dev": "tsc --watch",
|
||||
"pretest": "tsc",
|
||||
"build": "rollup -c && tsc --emitDeclarationOnly",
|
||||
"dev": "rollup -c --watch",
|
||||
"pretest": "rollup -c",
|
||||
"test": "bun test",
|
||||
"test:coverage": "bun test --coverage",
|
||||
"test:watch": "bun test --watch",
|
||||
"test:ci": "bun test --reporter=verbose",
|
||||
"lint": "biome lint src/ test/",
|
||||
"lint:fix": "biome lint --write src/ test/",
|
||||
"type-check": "tsc --noEmit",
|
||||
"check": "tsc --noEmit",
|
||||
"check:watch": "tsc --noEmit --watch",
|
||||
"format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\" \"*.{json,md,yml,yaml}\"",
|
||||
"format:check": "prettier --check \"src/**/*.ts\" \"test/**/*.ts\" \"*.{json,md,yml,yaml}\"",
|
||||
"clean": "rm -rf dist coverage",
|
||||
@@ -63,9 +73,14 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@biomejs/biome": "^2.2.4",
|
||||
"@rollup/plugin-alias": "^5.1.1",
|
||||
"@rollup/plugin-commonjs": "^28.0.6",
|
||||
"@rollup/plugin-node-resolve": "^16.0.1",
|
||||
"@types/bun": "latest",
|
||||
"@types/node": "^20.0.0",
|
||||
"prettier": "^3.0.0",
|
||||
"rollup": "^4.52.2",
|
||||
"rollup-plugin-typescript": "^1.0.1",
|
||||
"typescript": "^5.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
|
||||
37
rollup.config.js
Normal file
37
rollup.config.js
Normal file
@@ -0,0 +1,37 @@
|
||||
import alias from '@rollup/plugin-alias';
|
||||
import resolve from '@rollup/plugin-node-resolve';
|
||||
import commonjs from '@rollup/plugin-commonjs';
|
||||
import typescript from 'rollup-plugin-typescript';
|
||||
|
||||
export default [
|
||||
// CommonJS build
|
||||
{
|
||||
input: 'src/index.ts',
|
||||
plugins: [resolve(), commonjs(), typescript()],
|
||||
external: ['prettier', 'js-yaml'],
|
||||
output: {
|
||||
file: 'dist/index.js',
|
||||
format: 'cjs',
|
||||
sourcemap: true,
|
||||
},
|
||||
},
|
||||
// Browser build
|
||||
// Supported use case: importing the plugin from a bundler like Vite or Webpack
|
||||
// Semi-supported use case: importing the plugin directly in the browser through using import maps.
|
||||
{
|
||||
input: 'src/index.ts',
|
||||
plugins: [
|
||||
alias({
|
||||
entries: [{ find: 'prettier', replacement: 'prettier/standalone' }],
|
||||
}),
|
||||
resolve(),
|
||||
commonjs(),
|
||||
typescript(),
|
||||
],
|
||||
external: ['prettier/standalone', 'prettier/plugins/babel', 'js-yaml'],
|
||||
output: {
|
||||
file: 'dist/browser.js',
|
||||
format: 'esm',
|
||||
},
|
||||
},
|
||||
];
|
||||
166
src/index.ts
166
src/index.ts
@@ -1,3 +1,4 @@
|
||||
import { SupportLanguage, Parser, Printer } from 'prettier';
|
||||
import type { Plugin } from 'prettier';
|
||||
import * as yaml from 'js-yaml';
|
||||
import { getVendorExtensions } from './extensions/vendor-loader.js';
|
||||
@@ -32,9 +33,10 @@ import {
|
||||
|
||||
// Type definitions for better type safety
|
||||
interface OpenAPINode {
|
||||
type: 'openapi-json' | 'openapi-yaml';
|
||||
type: 'openapi';
|
||||
content: any;
|
||||
originalText: string;
|
||||
format: 'json' | 'yaml';
|
||||
}
|
||||
|
||||
interface PrettierPath {
|
||||
@@ -49,6 +51,66 @@ interface OpenAPIPluginOptions {
|
||||
// Load vendor extensions
|
||||
const vendorExtensions = getVendorExtensions();
|
||||
|
||||
// ============================================================================
|
||||
// UNIFIED PARSER FUNCTIONS
|
||||
// ============================================================================
|
||||
|
||||
/**
|
||||
* Unified parser that can handle both JSON and YAML OpenAPI files
|
||||
*/
|
||||
function parseOpenAPIFile(text: string, options?: any): OpenAPINode {
|
||||
// Try to detect the format based on file extension or content
|
||||
const filePath = options?.filepath || '';
|
||||
const isYamlFile = filePath.endsWith('.yaml') || filePath.endsWith('.yml');
|
||||
const isJsonFile = filePath.endsWith('.json');
|
||||
|
||||
// If we can't determine from extension, try to detect from content
|
||||
let format: 'json' | 'yaml' = 'json'; // default to JSON
|
||||
if (isYamlFile) {
|
||||
format = 'yaml';
|
||||
} else if (isJsonFile) {
|
||||
format = 'json';
|
||||
} else {
|
||||
// Try to detect format from content
|
||||
const trimmedText = text.trim();
|
||||
if (trimmedText.startsWith('{') || trimmedText.startsWith('[')) {
|
||||
format = 'json';
|
||||
} else {
|
||||
format = 'yaml';
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
let parsed: any;
|
||||
|
||||
if (format === 'json') {
|
||||
parsed = JSON.parse(text);
|
||||
} else {
|
||||
parsed = yaml.load(text, {
|
||||
schema: yaml.DEFAULT_SCHEMA,
|
||||
onWarning: (warning) => {
|
||||
// Handle YAML warnings if needed
|
||||
console.warn('YAML parsing warning:', warning);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Check if this is an OpenAPI file
|
||||
if (!isOpenAPIFile(parsed, filePath)) {
|
||||
throw new Error('Not an OpenAPI file');
|
||||
}
|
||||
|
||||
return {
|
||||
type: 'openapi',
|
||||
content: parsed,
|
||||
originalText: text,
|
||||
format: format,
|
||||
};
|
||||
} catch (error) {
|
||||
throw new Error(`Failed to parse OpenAPI ${format.toUpperCase()}: ${error}`);
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// FILE DETECTION FUNCTIONS
|
||||
// ============================================================================
|
||||
@@ -170,116 +232,62 @@ function isPathObject(obj: any): boolean {
|
||||
const plugin: Plugin = {
|
||||
languages: [
|
||||
{
|
||||
name: 'openapi-json',
|
||||
name: 'openapi',
|
||||
extensions: [
|
||||
'.openapi.json', '.swagger.json',
|
||||
// Support for component files
|
||||
'.json'
|
||||
// Accepting all JSON and YAML files so that component files used by $ref work
|
||||
'.json', '.yaml', '.yml'
|
||||
],
|
||||
parsers: ['openapi-json-parser'],
|
||||
},
|
||||
{
|
||||
name: 'openapi-yaml',
|
||||
extensions: [
|
||||
'.openapi.yaml', '.openapi.yml',
|
||||
'.swagger.yaml', '.swagger.yml',
|
||||
// Support for component files
|
||||
'.yaml', '.yml'
|
||||
],
|
||||
parsers: ['openapi-yaml-parser'],
|
||||
parsers: ['openapi-parser'],
|
||||
},
|
||||
],
|
||||
parsers: {
|
||||
'openapi-json-parser': {
|
||||
'openapi-parser': {
|
||||
parse: (text: string, options?: any): OpenAPINode => {
|
||||
try {
|
||||
const parsed = JSON.parse(text);
|
||||
|
||||
// Check if this is an OpenAPI file
|
||||
if (!isOpenAPIFile(parsed, options?.filepath)) {
|
||||
throw new Error('Not an OpenAPI file');
|
||||
}
|
||||
|
||||
return {
|
||||
type: 'openapi-json',
|
||||
content: parsed,
|
||||
originalText: text,
|
||||
};
|
||||
} catch (error) {
|
||||
throw new Error(`Failed to parse OpenAPI JSON: ${error}`);
|
||||
}
|
||||
return parseOpenAPIFile(text, options);
|
||||
},
|
||||
astFormat: 'openapi-json-ast',
|
||||
locStart: (node: OpenAPINode) => 0,
|
||||
locEnd: (node: OpenAPINode) => node.originalText?.length || 0,
|
||||
},
|
||||
'openapi-yaml-parser': {
|
||||
parse: (text: string, options?: any): OpenAPINode => {
|
||||
try {
|
||||
const parsed = yaml.load(text, {
|
||||
schema: yaml.DEFAULT_SCHEMA,
|
||||
onWarning: (warning) => {
|
||||
// Handle YAML warnings if needed
|
||||
console.warn('YAML parsing warning:', warning);
|
||||
}
|
||||
});
|
||||
|
||||
// Check if this is an OpenAPI file
|
||||
if (!isOpenAPIFile(parsed, options?.filepath)) {
|
||||
throw new Error('Not an OpenAPI file');
|
||||
}
|
||||
|
||||
return {
|
||||
type: 'openapi-yaml',
|
||||
content: parsed,
|
||||
originalText: text,
|
||||
};
|
||||
} catch (error) {
|
||||
throw new Error(`Failed to parse OpenAPI YAML: ${error}`);
|
||||
}
|
||||
},
|
||||
astFormat: 'openapi-yaml-ast',
|
||||
astFormat: 'openapi-ast',
|
||||
locStart: (node: OpenAPINode) => 0,
|
||||
locEnd: (node: OpenAPINode) => node.originalText?.length || 0,
|
||||
},
|
||||
},
|
||||
printers: {
|
||||
'openapi-json-ast': {
|
||||
'openapi-ast': {
|
||||
print: (path: PrettierPath, options?: any, print?: any, ...rest: any[]): string => {
|
||||
const node = path.getValue();
|
||||
return formatOpenAPIJSON(node.content, options);
|
||||
},
|
||||
},
|
||||
'openapi-yaml-ast': {
|
||||
print: (path: PrettierPath, options?: any, print?: any, ...rest: any[]): string => {
|
||||
const node = path.getValue();
|
||||
return formatOpenAPIYAML(node.content, options);
|
||||
return formatOpenAPI(node.content, node.format, options);
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
function formatOpenAPIJSON(content: any, options?: OpenAPIPluginOptions): string {
|
||||
/**
|
||||
* Unified formatter that outputs in the detected format
|
||||
*/
|
||||
function formatOpenAPI(content: any, format: 'json' | 'yaml', options?: OpenAPIPluginOptions): string {
|
||||
// Sort keys for better organization
|
||||
const sortedContent = sortOpenAPIKeys(content);
|
||||
|
||||
if (format === 'json') {
|
||||
// Format with proper indentation
|
||||
return JSON.stringify(sortedContent, null, options?.tabWidth || 2);
|
||||
}
|
||||
|
||||
function formatOpenAPIYAML(content: any, options?: OpenAPIPluginOptions): string {
|
||||
// Sort keys for better organization
|
||||
const sortedContent = sortOpenAPIKeys(content);
|
||||
|
||||
} else {
|
||||
// Format YAML with proper indentation and line breaks
|
||||
return yaml.dump(sortedContent, {
|
||||
indent: options?.tabWidth || 2,
|
||||
lineWidth: options?.printWidth || 80,
|
||||
noRefs: true,
|
||||
sortKeys: true,
|
||||
quotingType: '"',
|
||||
forceQuotes: false,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function formatOpenAPIJSON(content: any, options?: OpenAPIPluginOptions): string {
|
||||
return formatOpenAPI(content, 'json', options);
|
||||
}
|
||||
|
||||
function formatOpenAPIYAML(content: any, options?: OpenAPIPluginOptions): string {
|
||||
return formatOpenAPI(content, 'yaml', options);
|
||||
}
|
||||
|
||||
function sortOpenAPIKeys(obj: any): any {
|
||||
|
||||
@@ -44,17 +44,17 @@ describe('Build Tests', () => {
|
||||
const indexPath = path.join(process.cwd(), 'dist', 'index.js');
|
||||
const content = fs.readFileSync(indexPath, 'utf-8');
|
||||
|
||||
// Should have default export
|
||||
expect(content).toContain('export default');
|
||||
// Should have module.exports (CommonJS format)
|
||||
expect(content).toContain('module.exports');
|
||||
});
|
||||
|
||||
it('should have proper module structure', () => {
|
||||
const indexPath = path.join(process.cwd(), 'dist', 'index.js');
|
||||
const content = fs.readFileSync(indexPath, 'utf-8');
|
||||
|
||||
// Should be ES module
|
||||
expect(content).toContain('import');
|
||||
expect(content).toContain('export');
|
||||
// Should be CommonJS module
|
||||
expect(content).toContain('require');
|
||||
expect(content).toContain('module.exports');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -64,19 +64,22 @@ describe('Build Tests', () => {
|
||||
expect(packageJson.main).toBe('dist/index.js');
|
||||
});
|
||||
|
||||
it('should have correct module field', () => {
|
||||
it('should have correct types field', () => {
|
||||
const packageJson = JSON.parse(fs.readFileSync('package.json', 'utf-8'));
|
||||
expect(packageJson.module).toBe('dist/index.js');
|
||||
expect(packageJson.types).toBe('./dist/index.d.ts');
|
||||
});
|
||||
|
||||
it('should have correct type field', () => {
|
||||
it('should have correct exports field', () => {
|
||||
const packageJson = JSON.parse(fs.readFileSync('package.json', 'utf-8'));
|
||||
expect(packageJson.type).toBe('module');
|
||||
expect(packageJson.exports).toBeDefined();
|
||||
expect(packageJson.exports['.']).toBeDefined();
|
||||
expect(packageJson.exports['.'].default).toBe('./dist/index.js');
|
||||
});
|
||||
|
||||
it('should include dist in files array', () => {
|
||||
it('should include required files in files array', () => {
|
||||
const packageJson = JSON.parse(fs.readFileSync('package.json', 'utf-8'));
|
||||
expect(packageJson.files).toContain('dist');
|
||||
expect(packageJson.files).toContain('dist/index.js');
|
||||
expect(packageJson.files).toContain('dist/index.d.ts');
|
||||
});
|
||||
|
||||
it('should have required metadata', () => {
|
||||
|
||||
@@ -4,77 +4,77 @@ import plugin from '../src/index';
|
||||
describe('Coverage Tests', () => {
|
||||
describe('Error handling and edge cases', () => {
|
||||
it('should handle null and undefined content', () => {
|
||||
const jsonParser = plugin.parsers?.['openapi-json-parser'];
|
||||
expect(jsonParser).toBeDefined();
|
||||
const parser = plugin.parsers?.['openapi-parser'];
|
||||
expect(parser).toBeDefined();
|
||||
|
||||
// Test with null content
|
||||
expect(() => {
|
||||
// @ts-expect-error We are testing edge cases
|
||||
jsonParser?.parse('null', {});
|
||||
parser?.parse('null', { filepath: 'test.json' });
|
||||
}).toThrow();
|
||||
|
||||
// Test with undefined content
|
||||
expect(() => {
|
||||
// @ts-expect-error We are testing edge cases
|
||||
jsonParser?.parse('undefined', {});
|
||||
parser?.parse('undefined', { filepath: 'test.json' });
|
||||
}).toThrow();
|
||||
});
|
||||
|
||||
it('should handle non-object content', () => {
|
||||
const jsonParser = plugin.parsers?.['openapi-json-parser'];
|
||||
expect(jsonParser).toBeDefined();
|
||||
const parser = plugin.parsers?.['openapi-parser'];
|
||||
expect(parser).toBeDefined();
|
||||
|
||||
// Test with string content
|
||||
expect(() => {
|
||||
// @ts-expect-error We are testing edge cases
|
||||
jsonParser?.parse('"string"', {});
|
||||
parser?.parse('"string"', { filepath: 'test.json' });
|
||||
}).toThrow();
|
||||
|
||||
// Test with number content
|
||||
expect(() => {
|
||||
// @ts-expect-error We are testing edge cases
|
||||
jsonParser?.parse('123', {});
|
||||
parser?.parse('123', { filepath: 'test.json' });
|
||||
}).toThrow();
|
||||
});
|
||||
|
||||
it('should handle array content', () => {
|
||||
const jsonParser = plugin.parsers?.['openapi-json-parser'];
|
||||
expect(jsonParser).toBeDefined();
|
||||
const parser = plugin.parsers?.['openapi-parser'];
|
||||
expect(parser).toBeDefined();
|
||||
|
||||
// Test with array content
|
||||
expect(() => {
|
||||
// @ts-expect-error We are testing edge cases
|
||||
jsonParser?.parse('[]', {});
|
||||
parser?.parse('[]', { filepath: 'test.json' });
|
||||
}).toThrow();
|
||||
});
|
||||
|
||||
it('should handle malformed JSON', () => {
|
||||
const jsonParser = plugin.parsers?.['openapi-json-parser'];
|
||||
expect(jsonParser).toBeDefined();
|
||||
const parser = plugin.parsers?.['openapi-parser'];
|
||||
expect(parser).toBeDefined();
|
||||
|
||||
// Test with malformed JSON
|
||||
expect(() => {
|
||||
// @ts-expect-error We are testing edge cases
|
||||
jsonParser?.parse('{invalid json}', {});
|
||||
parser?.parse('{invalid json}', { filepath: 'test.json' });
|
||||
}).toThrow('Failed to parse OpenAPI JSON');
|
||||
});
|
||||
|
||||
it('should handle malformed YAML', () => {
|
||||
const yamlParser = plugin.parsers?.['openapi-yaml-parser'];
|
||||
expect(yamlParser).toBeDefined();
|
||||
const parser = plugin.parsers?.['openapi-parser'];
|
||||
expect(parser).toBeDefined();
|
||||
|
||||
// Test with malformed YAML
|
||||
expect(() => {
|
||||
// @ts-expect-error We are testing edge cases
|
||||
yamlParser?.parse('invalid: yaml: content:', {});
|
||||
parser?.parse('invalid: yaml: content:', { filepath: 'test.yaml' });
|
||||
}).toThrow('Failed to parse OpenAPI YAML');
|
||||
});
|
||||
});
|
||||
|
||||
describe('File path detection', () => {
|
||||
it('should detect OpenAPI files in component directories', () => {
|
||||
const yamlParser = plugin.parsers?.['openapi-yaml-parser'];
|
||||
expect(yamlParser).toBeDefined();
|
||||
const parser = plugin.parsers?.['openapi-parser'];
|
||||
expect(parser).toBeDefined();
|
||||
|
||||
const testYaml = `type: object
|
||||
properties:
|
||||
@@ -98,15 +98,16 @@ properties:
|
||||
|
||||
paths.forEach(path => {
|
||||
// @ts-expect-error We are testing edge cases
|
||||
const result = yamlParser?.parse(testYaml, { filepath: path });
|
||||
const result = parser?.parse(testYaml, { filepath: path });
|
||||
expect(result).toBeDefined();
|
||||
expect(result?.type).toBe('openapi-yaml');
|
||||
expect(result?.type).toBe('openapi');
|
||||
expect(result?.format).toBe('yaml');
|
||||
});
|
||||
});
|
||||
|
||||
it('should handle files without filepath', () => {
|
||||
const yamlParser = plugin.parsers?.['openapi-yaml-parser'];
|
||||
expect(yamlParser).toBeDefined();
|
||||
const parser = plugin.parsers?.['openapi-parser'];
|
||||
expect(parser).toBeDefined();
|
||||
|
||||
const testYaml = `openapi: 3.0.0
|
||||
info:
|
||||
@@ -114,16 +115,16 @@ info:
|
||||
version: 1.0.0`;
|
||||
|
||||
// @ts-expect-error We are testing edge cases
|
||||
const result = yamlParser?.parse(testYaml, {});
|
||||
const result = parser?.parse(testYaml, { filepath: 'test.yaml' });
|
||||
expect(result).toBeDefined();
|
||||
expect(result?.type).toBe('openapi-yaml');
|
||||
expect(result?.type).toBe('openapi');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Object type detection', () => {
|
||||
it('should detect operation objects', () => {
|
||||
const yamlParser = plugin.parsers?.['openapi-yaml-parser'];
|
||||
expect(yamlParser).toBeDefined();
|
||||
const parser = plugin.parsers?.['openapi-parser'];
|
||||
expect(parser).toBeDefined();
|
||||
|
||||
const operationYaml = `get:
|
||||
summary: Get users
|
||||
@@ -132,14 +133,14 @@ info:
|
||||
description: Success`;
|
||||
|
||||
// @ts-expect-error We are testing edge cases
|
||||
const result = yamlParser?.parse(operationYaml, { filepath: 'paths/users.yaml' });
|
||||
const result = parser?.parse(operationYaml, { filepath: 'paths/users.yaml' });
|
||||
expect(result).toBeDefined();
|
||||
expect(result?.type).toBe('openapi-yaml');
|
||||
expect(result?.type).toBe('openapi');
|
||||
});
|
||||
|
||||
it('should detect parameter objects', () => {
|
||||
const yamlParser = plugin.parsers?.['openapi-yaml-parser'];
|
||||
expect(yamlParser).toBeDefined();
|
||||
const parser = plugin.parsers?.['openapi-parser'];
|
||||
expect(parser).toBeDefined();
|
||||
|
||||
const parameterYaml = `name: id
|
||||
in: path
|
||||
@@ -148,14 +149,14 @@ schema:
|
||||
type: integer`;
|
||||
|
||||
// @ts-expect-error We are testing edge cases
|
||||
const result = yamlParser?.parse(parameterYaml, { filepath: 'components/parameters/UserId.yaml' });
|
||||
const result = parser?.parse(parameterYaml, { filepath: 'components/parameters/UserId.yaml' });
|
||||
expect(result).toBeDefined();
|
||||
expect(result?.type).toBe('openapi-yaml');
|
||||
expect(result?.type).toBe('openapi');
|
||||
});
|
||||
|
||||
it('should detect schema objects', () => {
|
||||
const yamlParser = plugin.parsers?.['openapi-yaml-parser'];
|
||||
expect(yamlParser).toBeDefined();
|
||||
const parser = plugin.parsers?.['openapi-parser'];
|
||||
expect(parser).toBeDefined();
|
||||
|
||||
const schemaYaml = `type: object
|
||||
properties:
|
||||
@@ -167,14 +168,14 @@ required:
|
||||
- id`;
|
||||
|
||||
// @ts-expect-error We are testing edge cases
|
||||
const result = yamlParser?.parse(schemaYaml, { filepath: 'components/schemas/User.yaml' });
|
||||
const result = parser?.parse(schemaYaml, { filepath: 'components/schemas/User.yaml' });
|
||||
expect(result).toBeDefined();
|
||||
expect(result?.type).toBe('openapi-yaml');
|
||||
expect(result?.type).toBe('openapi');
|
||||
});
|
||||
|
||||
it('should detect response objects', () => {
|
||||
const yamlParser = plugin.parsers?.['openapi-yaml-parser'];
|
||||
expect(yamlParser).toBeDefined();
|
||||
const parser = plugin.parsers?.['openapi-parser'];
|
||||
expect(parser).toBeDefined();
|
||||
|
||||
const responseYaml = `description: User response
|
||||
content:
|
||||
@@ -183,67 +184,67 @@ content:
|
||||
type: object`;
|
||||
|
||||
// @ts-expect-error We are testing edge cases
|
||||
const result = yamlParser?.parse(responseYaml, { filepath: 'components/responses/UserResponse.yaml' });
|
||||
const result = parser?.parse(responseYaml, { filepath: 'components/responses/UserResponse.yaml' });
|
||||
expect(result).toBeDefined();
|
||||
expect(result?.type).toBe('openapi-yaml');
|
||||
expect(result?.type).toBe('openapi');
|
||||
});
|
||||
|
||||
it('should detect security scheme objects', () => {
|
||||
const yamlParser = plugin.parsers?.['openapi-yaml-parser'];
|
||||
expect(yamlParser).toBeDefined();
|
||||
const parser = plugin.parsers?.['openapi-parser'];
|
||||
expect(parser).toBeDefined();
|
||||
|
||||
const securityYaml = `type: http
|
||||
scheme: bearer
|
||||
bearerFormat: JWT`;
|
||||
|
||||
// @ts-expect-error We are testing edge cases
|
||||
const result = yamlParser?.parse(securityYaml, { filepath: 'components/securitySchemes/BearerAuth.yaml' });
|
||||
const result = parser?.parse(securityYaml, { filepath: 'components/securitySchemes/BearerAuth.yaml' });
|
||||
expect(result).toBeDefined();
|
||||
expect(result?.type).toBe('openapi-yaml');
|
||||
expect(result?.type).toBe('openapi');
|
||||
});
|
||||
|
||||
it('should detect server objects', () => {
|
||||
const yamlParser = plugin.parsers?.['openapi-yaml-parser'];
|
||||
expect(yamlParser).toBeDefined();
|
||||
const parser = plugin.parsers?.['openapi-parser'];
|
||||
expect(parser).toBeDefined();
|
||||
|
||||
const serverYaml = `url: https://api.example.com
|
||||
description: Production server`;
|
||||
|
||||
// @ts-expect-error We are testing edge cases
|
||||
const result = yamlParser?.parse(serverYaml, { filepath: 'servers/production.yaml' });
|
||||
const result = parser?.parse(serverYaml, { filepath: 'servers/production.yaml' });
|
||||
expect(result).toBeDefined();
|
||||
expect(result?.type).toBe('openapi-yaml');
|
||||
expect(result?.type).toBe('openapi');
|
||||
});
|
||||
|
||||
it('should detect tag objects', () => {
|
||||
const yamlParser = plugin.parsers?.['openapi-yaml-parser'];
|
||||
expect(yamlParser).toBeDefined();
|
||||
const parser = plugin.parsers?.['openapi-parser'];
|
||||
expect(parser).toBeDefined();
|
||||
|
||||
const tagYaml = `name: users
|
||||
description: User management operations`;
|
||||
|
||||
// @ts-expect-error We are testing edge cases
|
||||
const result = yamlParser?.parse(tagYaml, { filepath: 'tags/users.yaml' });
|
||||
const result = parser?.parse(tagYaml, { filepath: 'tags/users.yaml' });
|
||||
expect(result).toBeDefined();
|
||||
expect(result?.type).toBe('openapi-yaml');
|
||||
expect(result?.type).toBe('openapi');
|
||||
});
|
||||
|
||||
it('should detect external docs objects', () => {
|
||||
const yamlParser = plugin.parsers?.['openapi-yaml-parser'];
|
||||
expect(yamlParser).toBeDefined();
|
||||
const parser = plugin.parsers?.['openapi-parser'];
|
||||
expect(parser).toBeDefined();
|
||||
|
||||
const externalDocsYaml = `url: https://example.com/docs
|
||||
description: External documentation`;
|
||||
|
||||
// @ts-expect-error We are testing edge cases
|
||||
const result = yamlParser?.parse(externalDocsYaml, { filepath: 'externalDocs/api.yaml' });
|
||||
const result = parser?.parse(externalDocsYaml, { filepath: 'externalDocs/api.yaml' });
|
||||
expect(result).toBeDefined();
|
||||
expect(result?.type).toBe('openapi-yaml');
|
||||
expect(result?.type).toBe('openapi');
|
||||
});
|
||||
|
||||
it('should detect webhook objects', () => {
|
||||
const yamlParser = plugin.parsers?.['openapi-yaml-parser'];
|
||||
expect(yamlParser).toBeDefined();
|
||||
const parser = plugin.parsers?.['openapi-parser'];
|
||||
expect(parser).toBeDefined();
|
||||
|
||||
const webhookYaml = `post:
|
||||
summary: New message webhook
|
||||
@@ -252,18 +253,19 @@ description: External documentation`;
|
||||
description: Success`;
|
||||
|
||||
// @ts-expect-error We are testing edge cases
|
||||
const result = yamlParser?.parse(webhookYaml, { filepath: 'webhooks/messageCreated.yaml' });
|
||||
const result = parser?.parse(webhookYaml, { filepath: 'webhooks/messageCreated.yaml' });
|
||||
expect(result).toBeDefined();
|
||||
expect(result?.type).toBe('openapi-yaml');
|
||||
expect(result?.type).toBe('openapi');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Sorting functions', () => {
|
||||
it('should handle path sorting by specificity', () => {
|
||||
const jsonPrinter = plugin.printers?.['openapi-json-ast'];
|
||||
expect(jsonPrinter).toBeDefined();
|
||||
const printer = plugin.printers?.['openapi-ast'];
|
||||
expect(printer).toBeDefined();
|
||||
|
||||
const testData = {
|
||||
type: 'openapi',
|
||||
content: {
|
||||
openapi: '3.0.0',
|
||||
info: { title: 'Test API', version: '1.0.0' },
|
||||
@@ -272,11 +274,13 @@ description: External documentation`;
|
||||
'/users': { get: {} },
|
||||
'/users/{id}/posts': { get: {} }
|
||||
}
|
||||
}
|
||||
},
|
||||
originalText: '',
|
||||
format: 'json'
|
||||
};
|
||||
|
||||
// @ts-expect-error We are testing edge cases
|
||||
const result = jsonPrinter?.print({ getValue: () => testData }, { tabWidth: 2 }, () => '');
|
||||
const result = printer?.print({ getValue: () => testData }, { tabWidth: 2 }, () => '');
|
||||
expect(result).toBeDefined();
|
||||
|
||||
if (result && typeof result === 'string') {
|
||||
@@ -290,10 +294,11 @@ description: External documentation`;
|
||||
});
|
||||
|
||||
it('should handle response code sorting', () => {
|
||||
const jsonPrinter = plugin.printers?.['openapi-json-ast'];
|
||||
expect(jsonPrinter).toBeDefined();
|
||||
const printer = plugin.printers?.['openapi-ast'];
|
||||
expect(printer).toBeDefined();
|
||||
|
||||
const testData = {
|
||||
type: 'openapi',
|
||||
content: {
|
||||
openapi: '3.0.0',
|
||||
info: { title: 'Test API', version: '1.0.0' },
|
||||
@@ -308,11 +313,13 @@ description: External documentation`;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
originalText: '',
|
||||
format: 'json'
|
||||
};
|
||||
|
||||
// @ts-expect-error We are testing edge cases
|
||||
const result = jsonPrinter?.print({ getValue: () => testData }, { tabWidth: 2 }, () => '');
|
||||
const result = printer?.print({ getValue: () => testData }, { tabWidth: 2 }, () => '');
|
||||
expect(result).toBeDefined();
|
||||
|
||||
if (result && typeof result === 'string') {
|
||||
@@ -328,10 +335,11 @@ description: External documentation`;
|
||||
|
||||
describe('Context key detection', () => {
|
||||
it('should handle nested path contexts', () => {
|
||||
const jsonPrinter = plugin.printers?.['openapi-json-ast'];
|
||||
expect(jsonPrinter).toBeDefined();
|
||||
const printer = plugin.printers?.['openapi-ast'];
|
||||
expect(printer).toBeDefined();
|
||||
|
||||
const testData = {
|
||||
type: 'openapi',
|
||||
content: {
|
||||
openapi: '3.0.0',
|
||||
info: { title: 'Test API', version: '1.0.0' },
|
||||
@@ -346,11 +354,13 @@ description: External documentation`;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
originalText: '',
|
||||
format: 'json'
|
||||
};
|
||||
|
||||
// @ts-expect-error We are testing edge cases
|
||||
const result = jsonPrinter?.print({ getValue: () => testData }, { tabWidth: 2 }, () => '');
|
||||
const result = printer?.print({ getValue: () => testData }, { tabWidth: 2 }, () => '');
|
||||
expect(result).toBeDefined();
|
||||
|
||||
if (result && typeof result === 'string') {
|
||||
|
||||
@@ -3,8 +3,8 @@ import plugin from '../src/index';
|
||||
|
||||
describe('Custom Extensions Support', () => {
|
||||
it('should handle custom extensions in top-level keys', () => {
|
||||
const jsonParser = plugin.parsers?.['openapi-json-parser'];
|
||||
expect(jsonParser).toBeDefined();
|
||||
const parser = plugin.parsers?.['openapi-parser'];
|
||||
expect(parser).toBeDefined();
|
||||
|
||||
const testJson = {
|
||||
'x-custom-field': 'value',
|
||||
@@ -15,14 +15,14 @@ describe('Custom Extensions Support', () => {
|
||||
};
|
||||
|
||||
// @ts-expect-error We are mocking things here
|
||||
const result = jsonParser?.parse(JSON.stringify(testJson), {});
|
||||
const result = parser?.parse(JSON.stringify(testJson), { filepath: 'test.json' });
|
||||
expect(result).toBeDefined();
|
||||
expect(result?.content).toBeDefined();
|
||||
});
|
||||
|
||||
it('should handle custom extensions in info section', () => {
|
||||
const jsonParser = plugin.parsers?.['openapi-json-parser'];
|
||||
expect(jsonParser).toBeDefined();
|
||||
const parser = plugin.parsers?.['openapi-parser'];
|
||||
expect(parser).toBeDefined();
|
||||
|
||||
const testJson = {
|
||||
'openapi': '3.0.0',
|
||||
@@ -36,15 +36,15 @@ describe('Custom Extensions Support', () => {
|
||||
};
|
||||
|
||||
// @ts-expect-error We are mocking things here
|
||||
const result = jsonParser?.parse(JSON.stringify(testJson), {});
|
||||
const result = parser?.parse(JSON.stringify(testJson), { filepath: 'test.json' });
|
||||
expect(result).toBeDefined();
|
||||
expect(result?.content.info).toBeDefined();
|
||||
expect(result?.content.info['x-api-id']).toBe('api-123');
|
||||
});
|
||||
|
||||
it('should handle custom extensions in operation objects', () => {
|
||||
const jsonParser = plugin.parsers?.['openapi-json-parser'];
|
||||
expect(jsonParser).toBeDefined();
|
||||
const parser = plugin.parsers?.['openapi-parser'];
|
||||
expect(parser).toBeDefined();
|
||||
|
||||
const testJson = {
|
||||
'openapi': '3.0.0',
|
||||
@@ -62,14 +62,14 @@ describe('Custom Extensions Support', () => {
|
||||
};
|
||||
|
||||
// @ts-expect-error We are mocking things here
|
||||
const result = jsonParser?.parse(JSON.stringify(testJson), {});
|
||||
const result = parser?.parse(JSON.stringify(testJson), { filepath: 'test.json' });
|
||||
expect(result).toBeDefined();
|
||||
expect(result?.content.paths['/test'].get['x-rate-limit']).toBe(100);
|
||||
});
|
||||
|
||||
it('should handle custom extensions in schema objects', () => {
|
||||
const jsonParser = plugin.parsers?.['openapi-json-parser'];
|
||||
expect(jsonParser).toBeDefined();
|
||||
const parser = plugin.parsers?.['openapi-parser'];
|
||||
expect(parser).toBeDefined();
|
||||
|
||||
const testJson = {
|
||||
'openapi': '3.0.0',
|
||||
@@ -89,14 +89,14 @@ describe('Custom Extensions Support', () => {
|
||||
};
|
||||
|
||||
// @ts-expect-error We are mocking things here
|
||||
const result = jsonParser?.parse(JSON.stringify(testJson), {});
|
||||
const result = parser?.parse(JSON.stringify(testJson), { filepath: 'test.json' });
|
||||
expect(result).toBeDefined();
|
||||
expect(result?.content.components.schemas.User['x-custom-type']).toBe('entity');
|
||||
});
|
||||
|
||||
it('should format JSON with custom extensions', () => {
|
||||
const jsonPrinter = plugin.printers?.['openapi-json-ast'];
|
||||
expect(jsonPrinter).toBeDefined();
|
||||
const printer = plugin.printers?.['openapi-ast'];
|
||||
expect(printer).toBeDefined();
|
||||
|
||||
const testData = {
|
||||
content: {
|
||||
@@ -109,15 +109,15 @@ describe('Custom Extensions Support', () => {
|
||||
};
|
||||
|
||||
// @ts-expect-error We are mocking things here so we don't need to pass a print function
|
||||
const result = jsonPrinter?.print({ getValue: () => testData }, { tabWidth: 2 }, () => '');
|
||||
const result = printer?.print({ getValue: () => testData }, { tabWidth: 2 }, () => '');
|
||||
expect(result).toBeDefined();
|
||||
expect(result).toContain('"x-custom-field"');
|
||||
expect(result).toContain('"openapi"');
|
||||
expect(result).toContain('x-custom-field');
|
||||
expect(result).toContain('openapi');
|
||||
});
|
||||
|
||||
it('should format YAML with custom extensions', () => {
|
||||
const yamlPrinter = plugin.printers?.['openapi-yaml-ast'];
|
||||
expect(yamlPrinter).toBeDefined();
|
||||
const printer = plugin.printers?.['openapi-ast'];
|
||||
expect(printer).toBeDefined();
|
||||
|
||||
const testData = {
|
||||
content: {
|
||||
@@ -130,15 +130,15 @@ describe('Custom Extensions Support', () => {
|
||||
};
|
||||
|
||||
// @ts-expect-error We are mocking things here so we don't need to pass a print function
|
||||
const result = yamlPrinter?.print({ getValue: () => testData }, { tabWidth: 2 }, () => '');
|
||||
const result = printer?.print({ getValue: () => testData }, { tabWidth: 2 }, () => '');
|
||||
expect(result).toBeDefined();
|
||||
expect(result).toContain('x-custom-field:');
|
||||
expect(result).toContain('openapi:');
|
||||
});
|
||||
|
||||
it('should handle unknown keys alphabetically at the end', () => {
|
||||
const jsonParser = plugin.parsers?.['openapi-json-parser'];
|
||||
expect(jsonParser).toBeDefined();
|
||||
const parser = plugin.parsers?.['openapi-parser'];
|
||||
expect(parser).toBeDefined();
|
||||
|
||||
const testJson = {
|
||||
'openapi': '3.0.0',
|
||||
@@ -149,15 +149,15 @@ describe('Custom Extensions Support', () => {
|
||||
};
|
||||
|
||||
// @ts-expect-error We are mocking things here
|
||||
const result = jsonParser?.parse(JSON.stringify(testJson), {});
|
||||
const result = parser?.parse(JSON.stringify(testJson), { filepath: 'test.json' });
|
||||
expect(result).toBeDefined();
|
||||
expect(result?.content).toBeDefined();
|
||||
});
|
||||
|
||||
describe('Custom extension positioning', () => {
|
||||
it('should position custom extensions correctly in top-level', () => {
|
||||
const jsonPrinter = plugin.printers?.['openapi-json-ast'];
|
||||
expect(jsonPrinter).toBeDefined();
|
||||
const printer = plugin.printers?.['openapi-ast'];
|
||||
expect(printer).toBeDefined();
|
||||
|
||||
const testData = {
|
||||
content: {
|
||||
@@ -170,19 +170,21 @@ describe('Custom Extensions Support', () => {
|
||||
};
|
||||
|
||||
// @ts-expect-error We are mocking things here
|
||||
const result = jsonPrinter?.print({ getValue: () => testData }, { tabWidth: 2 }, () => '');
|
||||
const result = printer?.print({ getValue: () => testData }, { tabWidth: 2 }, () => '');
|
||||
expect(result).toBeDefined();
|
||||
|
||||
if (!result) {
|
||||
throw new Error('Result is undefined');
|
||||
}
|
||||
|
||||
const resultString = result.toString();
|
||||
|
||||
// Custom extensions should come after standard keys
|
||||
const openapiIndex = result.toString().indexOf('"openapi"');
|
||||
const infoIndex = result.toString().indexOf('"info"');
|
||||
const pathsIndex = result.toString().indexOf('"paths"');
|
||||
const xCustomFieldIndex = result.toString().indexOf('"x-custom-field"');
|
||||
const xMetadataIndex = result.toString().indexOf('"x-metadata"');
|
||||
const openapiIndex = resultString.indexOf('openapi');
|
||||
const infoIndex = resultString.indexOf('info');
|
||||
const pathsIndex = resultString.indexOf('paths');
|
||||
const xCustomFieldIndex = resultString.indexOf('x-custom-field');
|
||||
const xMetadataIndex = resultString.indexOf('x-metadata');
|
||||
|
||||
expect(openapiIndex).toBeLessThan(infoIndex);
|
||||
expect(infoIndex).toBeLessThan(pathsIndex);
|
||||
@@ -191,8 +193,8 @@ describe('Custom Extensions Support', () => {
|
||||
});
|
||||
|
||||
it('should position custom extensions correctly in info section', () => {
|
||||
const jsonPrinter = plugin.printers?.['openapi-json-ast'];
|
||||
expect(jsonPrinter).toBeDefined();
|
||||
const printer = plugin.printers?.['openapi-ast'];
|
||||
expect(printer).toBeDefined();
|
||||
|
||||
const testData = {
|
||||
content: {
|
||||
@@ -208,19 +210,21 @@ describe('Custom Extensions Support', () => {
|
||||
};
|
||||
|
||||
// @ts-expect-error We are mocking things here
|
||||
const result = jsonPrinter?.print({ getValue: () => testData }, { tabWidth: 2 }, () => '');
|
||||
const result = printer?.print({ getValue: () => testData }, { tabWidth: 2 }, () => '');
|
||||
expect(result).toBeDefined();
|
||||
|
||||
if (!result) {
|
||||
throw new Error('Result is undefined');
|
||||
}
|
||||
|
||||
const resultString = result.toString();
|
||||
|
||||
// Custom extensions should come after standard keys
|
||||
const titleIndex = result.toString().indexOf('"title"');
|
||||
const descriptionIndex = result.toString().indexOf('"description"');
|
||||
const versionIndex = result.toString().indexOf('"version"');
|
||||
const xApiIdIndex = result.toString().indexOf('"x-api-id"');
|
||||
const xVersionInfoIndex = result.toString().indexOf('"x-version-info"');
|
||||
const titleIndex = resultString.indexOf('title');
|
||||
const descriptionIndex = resultString.indexOf('description');
|
||||
const versionIndex = resultString.indexOf('version');
|
||||
const xApiIdIndex = resultString.indexOf('x-api-id');
|
||||
const xVersionInfoIndex = resultString.indexOf('x-version-info');
|
||||
|
||||
expect(titleIndex).toBeLessThan(versionIndex);
|
||||
expect(versionIndex).toBeLessThan(descriptionIndex);
|
||||
@@ -229,8 +233,8 @@ describe('Custom Extensions Support', () => {
|
||||
});
|
||||
|
||||
it('should position custom extensions correctly in operation objects', () => {
|
||||
const jsonPrinter = plugin.printers?.['openapi-json-ast'];
|
||||
expect(jsonPrinter).toBeDefined();
|
||||
const printer = plugin.printers?.['openapi-ast'];
|
||||
expect(printer).toBeDefined();
|
||||
|
||||
const testData = {
|
||||
content: {
|
||||
@@ -250,24 +254,19 @@ describe('Custom Extensions Support', () => {
|
||||
};
|
||||
|
||||
// @ts-expect-error We are mocking things here
|
||||
const result = jsonPrinter?.print({ getValue: () => testData }, { tabWidth: 2 }, () => '');
|
||||
const result = printer?.print({ getValue: () => testData }, { tabWidth: 2 }, () => '');
|
||||
expect(result).toBeDefined();
|
||||
|
||||
if (!result) {
|
||||
throw new Error('Result is undefined');
|
||||
}
|
||||
|
||||
// Custom extensions should come after standard keys
|
||||
// Find the operation section specifically
|
||||
const operationStart = result.toString().indexOf('"get": {');
|
||||
// Find the end of the operation object
|
||||
const operationEnd = result.toString().indexOf('}', result.toString().lastIndexOf('"x-custom-auth"'));
|
||||
const operationSection = result.toString().substring(operationStart, operationEnd + 1);
|
||||
const resultString = result.toString();
|
||||
|
||||
const summaryIndex = operationSection.indexOf('"summary"');
|
||||
const responsesIndex = operationSection.indexOf('"responses"');
|
||||
const xRateLimitIndex = operationSection.indexOf('"x-rate-limit"');
|
||||
const xCustomAuthIndex = operationSection.indexOf('"x-custom-auth"');
|
||||
const summaryIndex = resultString.indexOf('summary');
|
||||
const responsesIndex = resultString.indexOf('responses');
|
||||
const xRateLimitIndex = resultString.indexOf('x-rate-limit');
|
||||
const xCustomAuthIndex = resultString.indexOf('x-custom-auth');
|
||||
|
||||
expect(summaryIndex).toBeLessThan(responsesIndex);
|
||||
expect(responsesIndex).toBeLessThan(xCustomAuthIndex);
|
||||
@@ -275,8 +274,8 @@ describe('Custom Extensions Support', () => {
|
||||
});
|
||||
|
||||
it('should position custom extensions correctly in schema objects', () => {
|
||||
const jsonPrinter = plugin.printers?.['openapi-json-ast'];
|
||||
expect(jsonPrinter).toBeDefined();
|
||||
const printer = plugin.printers?.['openapi-ast'];
|
||||
expect(printer).toBeDefined();
|
||||
|
||||
const testData = {
|
||||
content: {
|
||||
@@ -296,18 +295,20 @@ describe('Custom Extensions Support', () => {
|
||||
};
|
||||
|
||||
// @ts-expect-error We are mocking things here
|
||||
const result = jsonPrinter?.print({ getValue: () => testData }, { tabWidth: 2 }, () => '');
|
||||
const result = printer?.print({ getValue: () => testData }, { tabWidth: 2 }, () => '');
|
||||
expect(result).toBeDefined();
|
||||
|
||||
if (!result) {
|
||||
throw new Error('Result is undefined');
|
||||
}
|
||||
|
||||
const resultString = result.toString();
|
||||
|
||||
// Custom extensions should come after standard keys
|
||||
const typeIndex = result.toString().indexOf('"type"');
|
||||
const propertiesIndex = result.toString().indexOf('"properties"');
|
||||
const xCustomTypeIndex = result.toString().indexOf('"x-custom-type"');
|
||||
const xValidationRulesIndex = result.toString().indexOf('"x-validation-rules"');
|
||||
const typeIndex = resultString.indexOf('type');
|
||||
const propertiesIndex = resultString.indexOf('properties');
|
||||
const xCustomTypeIndex = resultString.indexOf('x-custom-type');
|
||||
const xValidationRulesIndex = resultString.indexOf('x-validation-rules');
|
||||
|
||||
expect(typeIndex).toBeLessThan(propertiesIndex);
|
||||
expect(propertiesIndex).toBeLessThan(xCustomTypeIndex);
|
||||
@@ -317,8 +318,8 @@ describe('Custom Extensions Support', () => {
|
||||
|
||||
describe('Unknown key handling', () => {
|
||||
it('should sort unknown keys alphabetically at the end', () => {
|
||||
const jsonPrinter = plugin.printers?.['openapi-json-ast'];
|
||||
expect(jsonPrinter).toBeDefined();
|
||||
const printer = plugin.printers?.['openapi-ast'];
|
||||
expect(printer).toBeDefined();
|
||||
|
||||
const testData = {
|
||||
content: {
|
||||
@@ -331,19 +332,21 @@ describe('Custom Extensions Support', () => {
|
||||
};
|
||||
|
||||
// @ts-expect-error We are mocking things here
|
||||
const result = jsonPrinter?.print({ getValue: () => testData }, { tabWidth: 2 }, () => '');
|
||||
const result = printer?.print({ getValue: () => testData }, { tabWidth: 2 }, () => '');
|
||||
expect(result).toBeDefined();
|
||||
|
||||
if (!result) {
|
||||
throw new Error('Result is undefined');
|
||||
}
|
||||
|
||||
const resultString = result.toString();
|
||||
|
||||
// Unknown keys should come after standard keys and be sorted alphabetically
|
||||
const openapiIndex = result.toString().indexOf('"openapi"');
|
||||
const infoIndex = result.toString().indexOf('"info"');
|
||||
const pathsIndex = result.toString().indexOf('"paths"');
|
||||
const anotherUnknownIndex = result.toString().indexOf('"another-unknown"');
|
||||
const unknownFieldIndex = result.toString().indexOf('"unknown-field"');
|
||||
const openapiIndex = resultString.indexOf('openapi');
|
||||
const infoIndex = resultString.indexOf('info');
|
||||
const pathsIndex = resultString.indexOf('paths');
|
||||
const anotherUnknownIndex = resultString.indexOf('another-unknown');
|
||||
const unknownFieldIndex = resultString.indexOf('unknown-field');
|
||||
|
||||
expect(openapiIndex).toBeLessThan(infoIndex);
|
||||
expect(infoIndex).toBeLessThan(pathsIndex);
|
||||
@@ -355,8 +358,8 @@ describe('Custom Extensions Support', () => {
|
||||
});
|
||||
|
||||
it('should handle mixed custom extensions and unknown keys', () => {
|
||||
const jsonPrinter = plugin.printers?.['openapi-json-ast'];
|
||||
expect(jsonPrinter).toBeDefined();
|
||||
const printer = plugin.printers?.['openapi-ast'];
|
||||
expect(printer).toBeDefined();
|
||||
|
||||
const testData = {
|
||||
content: {
|
||||
@@ -371,21 +374,23 @@ describe('Custom Extensions Support', () => {
|
||||
};
|
||||
|
||||
// @ts-expect-error We are mocking things here
|
||||
const result = jsonPrinter?.print({ getValue: () => testData }, { tabWidth: 2 }, () => '');
|
||||
const result = printer?.print({ getValue: () => 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 = result.toString().indexOf('"openapi"');
|
||||
const infoIndex = result.toString().indexOf('"info"');
|
||||
const pathsIndex = result.toString().indexOf('"paths"');
|
||||
const xCustomFieldIndex = result.toString().indexOf('"x-custom-field"');
|
||||
const xMetadataIndex = result.toString().indexOf('"x-metadata"');
|
||||
const anotherUnknownIndex = result.toString().indexOf('"another-unknown"');
|
||||
const unknownFieldIndex = result.toString().indexOf('"unknown-field"');
|
||||
const openapiIndex = resultString.indexOf('openapi');
|
||||
const infoIndex = resultString.indexOf('info');
|
||||
const pathsIndex = resultString.indexOf('paths');
|
||||
const xCustomFieldIndex = resultString.indexOf('x-custom-field');
|
||||
const xMetadataIndex = resultString.indexOf('x-metadata');
|
||||
const anotherUnknownIndex = resultString.indexOf('another-unknown');
|
||||
const unknownFieldIndex = resultString.indexOf('unknown-field');
|
||||
|
||||
expect(openapiIndex).toBeLessThan(infoIndex);
|
||||
expect(infoIndex).toBeLessThan(pathsIndex);
|
||||
|
||||
@@ -3,8 +3,8 @@ import plugin from '../src/index';
|
||||
|
||||
describe('File Detection Tests', () => {
|
||||
it('should detect OpenAPI root files', () => {
|
||||
const yamlParser = plugin.parsers?.['openapi-yaml-parser'];
|
||||
expect(yamlParser).toBeDefined();
|
||||
const parser = plugin.parsers?.['openapi-parser'];
|
||||
expect(parser).toBeDefined();
|
||||
|
||||
const testYaml = `openapi: 3.0.0
|
||||
info:
|
||||
@@ -18,16 +18,17 @@ paths:
|
||||
description: Success`;
|
||||
|
||||
// @ts-expect-error We are mocking things here
|
||||
const result = yamlParser?.parse(testYaml, { filepath: 'openapi.yaml' });
|
||||
const result = parser?.parse(testYaml, { filepath: 'openapi.yaml' });
|
||||
|
||||
expect(result).toBeDefined();
|
||||
expect(result?.type).toBe('openapi-yaml');
|
||||
expect(result?.type).toBe('openapi');
|
||||
expect(result?.format).toBe('yaml');
|
||||
expect(result?.content.openapi).toBe('3.0.0');
|
||||
});
|
||||
|
||||
it('should detect partial schema files', () => {
|
||||
const yamlParser = plugin.parsers?.['openapi-yaml-parser'];
|
||||
expect(yamlParser).toBeDefined();
|
||||
const parser = plugin.parsers?.['openapi-parser'];
|
||||
expect(parser).toBeDefined();
|
||||
|
||||
const schemaYaml = `type: object
|
||||
properties:
|
||||
@@ -40,16 +41,17 @@ required:
|
||||
- name`;
|
||||
|
||||
// @ts-expect-error We are mocking things here
|
||||
const result = yamlParser?.parse(schemaYaml, { filepath: 'components/schemas/User.yaml' });
|
||||
const result = parser?.parse(schemaYaml, { filepath: 'components/schemas/User.yaml' });
|
||||
|
||||
expect(result).toBeDefined();
|
||||
expect(result?.type).toBe('openapi-yaml');
|
||||
expect(result?.type).toBe('openapi');
|
||||
expect(result?.format).toBe('yaml');
|
||||
expect(result?.content.type).toBe('object');
|
||||
});
|
||||
|
||||
it('should detect parameter files', () => {
|
||||
const yamlParser = plugin.parsers?.['openapi-yaml-parser'];
|
||||
expect(yamlParser).toBeDefined();
|
||||
const parser = plugin.parsers?.['openapi-parser'];
|
||||
expect(parser).toBeDefined();
|
||||
|
||||
const parameterYaml = `name: id
|
||||
in: path
|
||||
@@ -59,16 +61,17 @@ schema:
|
||||
type: integer`;
|
||||
|
||||
// @ts-expect-error We are mocking things here
|
||||
const result = yamlParser?.parse(parameterYaml, { filepath: 'components/parameters/UserId.yaml' });
|
||||
const result = parser?.parse(parameterYaml, { filepath: 'components/parameters/UserId.yaml' });
|
||||
|
||||
expect(result).toBeDefined();
|
||||
expect(result?.type).toBe('openapi-yaml');
|
||||
expect(result?.type).toBe('openapi');
|
||||
expect(result?.format).toBe('yaml');
|
||||
expect(result?.content.name).toBe('id');
|
||||
});
|
||||
|
||||
it('should detect response files', () => {
|
||||
const yamlParser = plugin.parsers?.['openapi-yaml-parser'];
|
||||
expect(yamlParser).toBeDefined();
|
||||
const parser = plugin.parsers?.['openapi-parser'];
|
||||
expect(parser).toBeDefined();
|
||||
|
||||
const responseYaml = `description: User response
|
||||
content:
|
||||
@@ -82,16 +85,17 @@ content:
|
||||
type: string`;
|
||||
|
||||
// @ts-expect-error We are mocking things here
|
||||
const result = yamlParser?.parse(responseYaml, { filepath: 'components/responses/UserResponse.yaml' });
|
||||
const result = parser?.parse(responseYaml, { filepath: 'components/responses/UserResponse.yaml' });
|
||||
|
||||
expect(result).toBeDefined();
|
||||
expect(result?.type).toBe('openapi-yaml');
|
||||
expect(result?.type).toBe('openapi');
|
||||
expect(result?.format).toBe('yaml');
|
||||
expect(result?.content.description).toBe('User response');
|
||||
});
|
||||
|
||||
it('should detect path files', () => {
|
||||
const yamlParser = plugin.parsers?.['openapi-yaml-parser'];
|
||||
expect(yamlParser).toBeDefined();
|
||||
const parser = plugin.parsers?.['openapi-parser'];
|
||||
expect(parser).toBeDefined();
|
||||
|
||||
const pathYaml = `get:
|
||||
summary: Get users
|
||||
@@ -107,17 +111,18 @@ post:
|
||||
type: object`;
|
||||
|
||||
// @ts-expect-error We are mocking things here
|
||||
const result = yamlParser?.parse(pathYaml, { filepath: 'paths/users.yaml' });
|
||||
const result = parser?.parse(pathYaml, { filepath: 'paths/users.yaml' });
|
||||
|
||||
expect(result).toBeDefined();
|
||||
expect(result?.type).toBe('openapi-yaml');
|
||||
expect(result?.type).toBe('openapi');
|
||||
expect(result?.format).toBe('yaml');
|
||||
expect(result?.content.get).toBeDefined();
|
||||
expect(result?.content.post).toBeDefined();
|
||||
});
|
||||
|
||||
it('should detect security scheme files', () => {
|
||||
const yamlParser = plugin.parsers?.['openapi-yaml-parser'];
|
||||
expect(yamlParser).toBeDefined();
|
||||
const parser = plugin.parsers?.['openapi-parser'];
|
||||
expect(parser).toBeDefined();
|
||||
|
||||
const securityYaml = `type: http
|
||||
scheme: bearer
|
||||
@@ -125,42 +130,44 @@ bearerFormat: JWT
|
||||
description: JWT authentication`;
|
||||
|
||||
// @ts-expect-error We are mocking things here
|
||||
const result = yamlParser?.parse(securityYaml, { filepath: 'components/securitySchemes/BearerAuth.yaml' });
|
||||
const result = parser?.parse(securityYaml, { filepath: 'components/securitySchemes/BearerAuth.yaml' });
|
||||
|
||||
expect(result).toBeDefined();
|
||||
expect(result?.type).toBe('openapi-yaml');
|
||||
expect(result?.type).toBe('openapi');
|
||||
expect(result?.format).toBe('yaml');
|
||||
expect(result?.content.type).toBe('http');
|
||||
});
|
||||
|
||||
it('should reject non-OpenAPI files', () => {
|
||||
const yamlParser = plugin.parsers?.['openapi-yaml-parser'];
|
||||
expect(yamlParser).toBeDefined();
|
||||
const parser = plugin.parsers?.['openapi-parser'];
|
||||
expect(parser).toBeDefined();
|
||||
|
||||
const nonOpenAPIYaml = `name: John
|
||||
age: 30
|
||||
city: New York`;
|
||||
|
||||
// @ts-expect-error We are mocking things here
|
||||
expect(() => yamlParser?.parse(nonOpenAPIYaml, { filepath: 'config/data.yaml' })).toThrow('Not an OpenAPI file');
|
||||
expect(() => parser?.parse(nonOpenAPIYaml, { filepath: 'config/data.yaml' })).toThrow('Not an OpenAPI file');
|
||||
});
|
||||
|
||||
it('should accept files in OpenAPI directories even with simple content', () => {
|
||||
const yamlParser = plugin.parsers?.['openapi-yaml-parser'];
|
||||
expect(yamlParser).toBeDefined();
|
||||
const parser = plugin.parsers?.['openapi-parser'];
|
||||
expect(parser).toBeDefined();
|
||||
|
||||
const simpleYaml = `name: John
|
||||
age: 30
|
||||
city: New York`;
|
||||
|
||||
// @ts-expect-error We are mocking things here
|
||||
const result = yamlParser?.parse(simpleYaml, { filepath: 'components/schemas/User.yaml' });
|
||||
const result = parser?.parse(simpleYaml, { filepath: 'components/schemas/User.yaml' });
|
||||
expect(result).toBeDefined();
|
||||
expect(result?.type).toBe('openapi-yaml');
|
||||
expect(result?.type).toBe('openapi');
|
||||
expect(result?.format).toBe('yaml');
|
||||
});
|
||||
|
||||
it('should support component directory patterns', () => {
|
||||
const yamlParser = plugin.parsers?.['openapi-yaml-parser'];
|
||||
expect(yamlParser).toBeDefined();
|
||||
const parser = plugin.parsers?.['openapi-parser'];
|
||||
expect(parser).toBeDefined();
|
||||
|
||||
const componentYaml = `type: object
|
||||
properties:
|
||||
@@ -184,9 +191,10 @@ properties:
|
||||
|
||||
paths.forEach(path => {
|
||||
// @ts-expect-error We are mocking things here
|
||||
const result = yamlParser?.parse(componentYaml, { filepath: path });
|
||||
const result = parser?.parse(componentYaml, { filepath: path });
|
||||
expect(result).toBeDefined();
|
||||
expect(result?.type).toBe('openapi-yaml');
|
||||
expect(result?.type).toBe('openapi');
|
||||
expect(result?.format).toBe('yaml');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -213,15 +213,18 @@ describe('Integration Tests', () => {
|
||||
]
|
||||
};
|
||||
|
||||
const jsonPrinter = plugin.printers?.['openapi-json-ast'];
|
||||
expect(jsonPrinter).toBeDefined();
|
||||
const printer = plugin.printers?.['openapi-ast'];
|
||||
expect(printer).toBeDefined();
|
||||
|
||||
const testData = {
|
||||
content: openApiContent
|
||||
type: 'openapi',
|
||||
content: openApiContent,
|
||||
originalText: '',
|
||||
format: 'json'
|
||||
};
|
||||
|
||||
// @ts-expect-error We are mocking things here
|
||||
const result = jsonPrinter?.print({ getValue: () => testData }, { tabWidth: 2 }, () => '');
|
||||
const result = printer?.print({ getValue: () => testData }, { tabWidth: 2 }, () => '');
|
||||
expect(result).toBeDefined();
|
||||
|
||||
if (result && typeof result === 'string') {
|
||||
@@ -362,15 +365,18 @@ describe('Integration Tests', () => {
|
||||
]
|
||||
};
|
||||
|
||||
const jsonPrinter = plugin.printers?.['openapi-json-ast'];
|
||||
expect(jsonPrinter).toBeDefined();
|
||||
const printer = plugin.printers?.['openapi-ast'];
|
||||
expect(printer).toBeDefined();
|
||||
|
||||
const testData = {
|
||||
content: swaggerContent
|
||||
type: 'openapi',
|
||||
content: swaggerContent,
|
||||
originalText: '',
|
||||
format: 'json'
|
||||
};
|
||||
|
||||
// @ts-expect-error We are mocking things here
|
||||
const result = jsonPrinter?.print({ getValue: () => testData }, { tabWidth: 2 }, () => '');
|
||||
const result = printer?.print({ getValue: () => testData }, { tabWidth: 2 }, () => '');
|
||||
expect(result).toBeDefined();
|
||||
|
||||
if (result && typeof result === 'string') {
|
||||
@@ -413,15 +419,18 @@ describe('Integration Tests', () => {
|
||||
}
|
||||
};
|
||||
|
||||
const yamlPrinter = plugin.printers?.['openapi-yaml-ast'];
|
||||
expect(yamlPrinter).toBeDefined();
|
||||
const printer = plugin.printers?.['openapi-ast'];
|
||||
expect(printer).toBeDefined();
|
||||
|
||||
const testData = {
|
||||
content: yamlContent
|
||||
type: 'openapi',
|
||||
content: yamlContent,
|
||||
originalText: '',
|
||||
format: 'yaml'
|
||||
};
|
||||
|
||||
// @ts-expect-error We are mocking things here
|
||||
const result = yamlPrinter?.print({ getValue: () => testData }, { tabWidth: 2 }, () => '');
|
||||
const result = printer?.print({ getValue: () => testData }, { tabWidth: 2 }, () => '');
|
||||
expect(result).toBeDefined();
|
||||
|
||||
if (result) {
|
||||
@@ -442,33 +451,33 @@ describe('Integration Tests', () => {
|
||||
|
||||
describe('Error handling', () => {
|
||||
it('should handle malformed JSON gracefully', () => {
|
||||
const jsonParser = plugin.parsers?.['openapi-json-parser'];
|
||||
expect(jsonParser).toBeDefined();
|
||||
const parser = plugin.parsers?.['openapi-parser'];
|
||||
expect(parser).toBeDefined();
|
||||
|
||||
const malformedJson = '{"openapi": "3.0.0", "info": {';
|
||||
|
||||
// @ts-expect-error We are mocking things here
|
||||
expect(() => jsonParser?.parse(malformedJson, {})).toThrow();
|
||||
expect(() => parser?.parse(malformedJson, { filepath: 'test.json' })).toThrow();
|
||||
});
|
||||
|
||||
it('should handle malformed YAML gracefully', () => {
|
||||
const yamlParser = plugin.parsers?.['openapi-yaml-parser'];
|
||||
expect(yamlParser).toBeDefined();
|
||||
const parser = plugin.parsers?.['openapi-parser'];
|
||||
expect(parser).toBeDefined();
|
||||
|
||||
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(() => yamlParser?.parse(malformedYaml, {})).toThrow();
|
||||
expect(() => parser?.parse(malformedYaml, { filepath: 'test.yaml' })).toThrow();
|
||||
});
|
||||
|
||||
it('should reject non-OpenAPI content', () => {
|
||||
const jsonParser = plugin.parsers?.['openapi-json-parser'];
|
||||
expect(jsonParser).toBeDefined();
|
||||
const parser = plugin.parsers?.['openapi-parser'];
|
||||
expect(parser).toBeDefined();
|
||||
|
||||
const nonOpenAPI = '{"name": "John", "age": 30}';
|
||||
|
||||
// @ts-expect-error We are mocking things here
|
||||
expect(() => jsonParser?.parse(nonOpenAPI, {})).toThrow('Not an OpenAPI file');
|
||||
expect(() => parser?.parse(nonOpenAPI, { filepath: 'test.json' })).toThrow('Not an OpenAPI file');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -497,17 +506,20 @@ describe('Integration Tests', () => {
|
||||
};
|
||||
}
|
||||
|
||||
const jsonPrinter = plugin.printers?.['openapi-json-ast'];
|
||||
expect(jsonPrinter).toBeDefined();
|
||||
const printer = plugin.printers?.['openapi-ast'];
|
||||
expect(printer).toBeDefined();
|
||||
|
||||
const testData = {
|
||||
content: largeOpenAPI
|
||||
type: 'openapi',
|
||||
content: largeOpenAPI,
|
||||
originalText: '',
|
||||
format: 'json'
|
||||
};
|
||||
|
||||
const startTime = Date.now();
|
||||
|
||||
// @ts-expect-error We are mocking things here
|
||||
const result = jsonPrinter?.print({ getValue: () => testData }, { tabWidth: 2 }, () => '');
|
||||
const result = printer?.print({ getValue: () => testData }, { tabWidth: 2 }, () => '');
|
||||
|
||||
const endTime = Date.now();
|
||||
const duration = endTime - startTime;
|
||||
|
||||
@@ -4,10 +4,11 @@ import plugin from '../src/index';
|
||||
describe('Key Ordering Tests', () => {
|
||||
describe('Info section key ordering', () => {
|
||||
it('should sort info keys correctly', () => {
|
||||
const jsonPrinter = plugin.printers?.['openapi-json-ast'];
|
||||
expect(jsonPrinter).toBeDefined();
|
||||
const printer = plugin.printers?.['openapi-ast'];
|
||||
expect(printer).toBeDefined();
|
||||
|
||||
const testData = {
|
||||
type: 'openapi',
|
||||
content: {
|
||||
openapi: '3.0.0',
|
||||
info: {
|
||||
@@ -18,23 +19,27 @@ describe('Key Ordering Tests', () => {
|
||||
contact: { name: 'API Team', email: 'api@example.com' },
|
||||
license: { name: 'MIT', url: 'https://opensource.org/licenses/MIT' }
|
||||
}
|
||||
}
|
||||
},
|
||||
originalText: '',
|
||||
format: 'json'
|
||||
};
|
||||
// @ts-expect-error We are mocking things here so we don't need to pass a print function
|
||||
const result = jsonPrinter?.print({ getValue: () => testData }, { tabWidth: 2 });
|
||||
const result = printer?.print({ getValue: () => testData }, { tabWidth: 2 });
|
||||
expect(result).toBeDefined();
|
||||
|
||||
if (!result) {
|
||||
throw new Error('Result is undefined');
|
||||
}
|
||||
|
||||
const resultString = result.toString();
|
||||
|
||||
// Check that info keys appear in the correct order
|
||||
const titleIndex = result.toString().indexOf('"title"');
|
||||
const versionIndex = result.toString().indexOf('"version"');
|
||||
const descriptionIndex = result.toString().indexOf('"description"');
|
||||
const termsOfServiceIndex = result.toString().indexOf('"termsOfService"');
|
||||
const contactIndex = result.toString().indexOf('"contact"');
|
||||
const licenseIndex = result.toString().indexOf('"license"');
|
||||
const titleIndex = resultString.indexOf('title');
|
||||
const versionIndex = resultString.indexOf('version');
|
||||
const descriptionIndex = resultString.indexOf('description');
|
||||
const termsOfServiceIndex = resultString.indexOf('termsOfService');
|
||||
const contactIndex = resultString.indexOf('contact');
|
||||
const licenseIndex = resultString.indexOf('license');
|
||||
|
||||
expect(titleIndex).toBeLessThan(versionIndex);
|
||||
expect(versionIndex).toBeLessThan(descriptionIndex);
|
||||
@@ -46,10 +51,11 @@ describe('Key Ordering Tests', () => {
|
||||
|
||||
describe('Operation key ordering', () => {
|
||||
it('should sort operation keys correctly', () => {
|
||||
const jsonPrinter = plugin.printers?.['openapi-json-ast'];
|
||||
expect(jsonPrinter).toBeDefined();
|
||||
const printer = plugin.printers?.['openapi-ast'];
|
||||
expect(printer).toBeDefined();
|
||||
|
||||
const testData = {
|
||||
type: 'openapi',
|
||||
content: {
|
||||
openapi: '3.0.0',
|
||||
info: { title: 'Test API', version: '1.0.0' },
|
||||
@@ -70,29 +76,33 @@ describe('Key Ordering Tests', () => {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
originalText: '',
|
||||
format: 'json'
|
||||
};
|
||||
|
||||
// @ts-expect-error We are mocking things here so we don't need to pass a print function
|
||||
const result = jsonPrinter?.print({ getValue: () => testData }, { tabWidth: 2 });
|
||||
const result = printer?.print({ getValue: () => testData }, { tabWidth: 2 });
|
||||
expect(result).toBeDefined();
|
||||
|
||||
if (!result) {
|
||||
throw new Error('Result is undefined');
|
||||
}
|
||||
|
||||
const resultString = result.toString();
|
||||
|
||||
// Check that operation keys appear in the correct order
|
||||
const summaryIndex = result.toString().indexOf('"summary"');
|
||||
const operationIdIndex = result.toString().indexOf('"operationId"');
|
||||
const descriptionIndex = result.toString().indexOf('"description"');
|
||||
const tagsIndex = result.toString().indexOf('"tags"');
|
||||
const deprecatedIndex = result.toString().indexOf('"deprecated"');
|
||||
const securityIndex = result.toString().indexOf('"security"');
|
||||
const serversIndex = result.toString().indexOf('"servers"');
|
||||
const parametersIndex = result.toString().indexOf('"parameters"');
|
||||
const requestBodyIndex = result.toString().indexOf('"requestBody"');
|
||||
const responsesIndex = result.toString().indexOf('"responses"');
|
||||
const callbacksIndex = result.toString().indexOf('"callbacks"');
|
||||
const summaryIndex = resultString.indexOf('summary');
|
||||
const operationIdIndex = resultString.indexOf('operationId');
|
||||
const descriptionIndex = resultString.indexOf('description');
|
||||
const tagsIndex = resultString.indexOf('tags');
|
||||
const deprecatedIndex = resultString.indexOf('deprecated');
|
||||
const securityIndex = resultString.indexOf('security');
|
||||
const serversIndex = resultString.indexOf('servers');
|
||||
const parametersIndex = resultString.indexOf('parameters');
|
||||
const requestBodyIndex = resultString.indexOf('requestBody');
|
||||
const responsesIndex = resultString.indexOf('responses');
|
||||
const callbacksIndex = resultString.indexOf('callbacks');
|
||||
|
||||
expect(summaryIndex).toBeLessThan(operationIdIndex);
|
||||
expect(operationIdIndex).toBeLessThan(descriptionIndex);
|
||||
@@ -109,8 +119,8 @@ describe('Key Ordering Tests', () => {
|
||||
|
||||
describe('Schema key ordering', () => {
|
||||
it('should sort schema keys correctly', () => {
|
||||
const jsonPrinter = plugin.printers?.['openapi-json-ast'];
|
||||
expect(jsonPrinter).toBeDefined();
|
||||
const printer = plugin.printers?.['openapi-ast'];
|
||||
expect(printer).toBeDefined();
|
||||
|
||||
const testData = {
|
||||
content: {
|
||||
@@ -159,53 +169,48 @@ describe('Key Ordering Tests', () => {
|
||||
};
|
||||
|
||||
// @ts-expect-error We are mocking things here so we don't need to pass a print function
|
||||
const result = jsonPrinter?.print({ getValue: () => testData }, { tabWidth: 2 });
|
||||
const result = printer?.print({ getValue: () => testData }, { tabWidth: 2 });
|
||||
expect(result).toBeDefined();
|
||||
|
||||
if (!result) {
|
||||
throw new Error('Result is undefined');
|
||||
}
|
||||
|
||||
// Check that schema keys appear in the correct order
|
||||
// Find the schema section specifically
|
||||
const schemaStart = result.toString().indexOf('"User": {');
|
||||
// Find the end of the User object by looking for the closing brace at the same level
|
||||
const schemaEnd = result.toString().indexOf('}', result.toString().lastIndexOf('"xml"'));
|
||||
const schemaSection = result.toString().substring(schemaStart, schemaEnd + 1);
|
||||
const resultString = result.toString();
|
||||
|
||||
const typeIndex = schemaSection.indexOf('"type"');
|
||||
const formatIndex = schemaSection.indexOf('"format"');
|
||||
const titleIndex = schemaSection.indexOf('"title"');
|
||||
const descriptionIndex = schemaSection.indexOf('"description"');
|
||||
const defaultIndex = schemaSection.indexOf('"default"');
|
||||
const exampleIndex = schemaSection.indexOf('"example"');
|
||||
const examplesIndex = schemaSection.indexOf('"examples"');
|
||||
const enumIndex = schemaSection.indexOf('"enum"');
|
||||
const constIndex = schemaSection.indexOf('"const"');
|
||||
const multipleOfIndex = schemaSection.indexOf('"multipleOf"');
|
||||
const maximumIndex = schemaSection.indexOf('"maximum"');
|
||||
const exclusiveMaximumIndex = schemaSection.indexOf('"exclusiveMaximum"');
|
||||
const minimumIndex = schemaSection.indexOf('"minimum"');
|
||||
const exclusiveMinimumIndex = schemaSection.indexOf('"exclusiveMinimum"');
|
||||
const maxLengthIndex = schemaSection.indexOf('"maxLength"');
|
||||
const minLengthIndex = schemaSection.indexOf('"minLength"');
|
||||
const patternIndex = schemaSection.indexOf('"pattern"');
|
||||
const maxItemsIndex = schemaSection.indexOf('"maxItems"');
|
||||
const minItemsIndex = schemaSection.indexOf('"minItems"');
|
||||
const uniqueItemsIndex = schemaSection.indexOf('"uniqueItems"');
|
||||
const maxPropertiesIndex = schemaSection.indexOf('"maxProperties"');
|
||||
const minPropertiesIndex = schemaSection.indexOf('"minProperties"');
|
||||
const requiredIndex = schemaSection.indexOf('"required"');
|
||||
const propertiesIndex = schemaSection.indexOf('"properties"');
|
||||
const itemsIndex = schemaSection.indexOf('"items"');
|
||||
const allOfIndex = schemaSection.indexOf('"allOf"');
|
||||
const oneOfIndex = schemaSection.indexOf('"oneOf"');
|
||||
const anyOfIndex = schemaSection.indexOf('"anyOf"');
|
||||
const notIndex = schemaSection.indexOf('"not"');
|
||||
const discriminatorIndex = schemaSection.indexOf('"discriminator"');
|
||||
const xmlIndex = schemaSection.indexOf('"xml"');
|
||||
const externalDocsIndex = schemaSection.indexOf('"externalDocs"');
|
||||
const deprecatedIndex = schemaSection.indexOf('"deprecated"');
|
||||
const typeIndex = resultString.indexOf('type:');
|
||||
const formatIndex = resultString.indexOf('format:');
|
||||
const titleIndex = resultString.indexOf('title:');
|
||||
const descriptionIndex = resultString.indexOf('description:');
|
||||
const defaultIndex = resultString.indexOf('default:');
|
||||
const exampleIndex = resultString.indexOf('example:');
|
||||
const examplesIndex = resultString.indexOf('examples:');
|
||||
const enumIndex = resultString.indexOf('enum:');
|
||||
const constIndex = resultString.indexOf('const:');
|
||||
const multipleOfIndex = resultString.indexOf('multipleOf:');
|
||||
const maximumIndex = resultString.indexOf('maximum:');
|
||||
const exclusiveMaximumIndex = resultString.indexOf('exclusiveMaximum:');
|
||||
const minimumIndex = resultString.indexOf('minimum:');
|
||||
const exclusiveMinimumIndex = resultString.indexOf('exclusiveMinimum:');
|
||||
const maxLengthIndex = resultString.indexOf('maxLength:');
|
||||
const minLengthIndex = resultString.indexOf('minLength:');
|
||||
const patternIndex = resultString.indexOf('pattern:');
|
||||
const maxItemsIndex = resultString.indexOf('maxItems:');
|
||||
const minItemsIndex = resultString.indexOf('minItems:');
|
||||
const uniqueItemsIndex = resultString.indexOf('uniqueItems:');
|
||||
const maxPropertiesIndex = resultString.indexOf('maxProperties:');
|
||||
const minPropertiesIndex = resultString.indexOf('minProperties:');
|
||||
const requiredIndex = resultString.indexOf('required:');
|
||||
const propertiesIndex = resultString.indexOf('properties:');
|
||||
const itemsIndex = resultString.indexOf('items:');
|
||||
const allOfIndex = resultString.indexOf('allOf:');
|
||||
const oneOfIndex = resultString.indexOf('oneOf:');
|
||||
const anyOfIndex = resultString.indexOf('anyOf:');
|
||||
const notIndex = resultString.indexOf('not:');
|
||||
const discriminatorIndex = resultString.indexOf('discriminator:');
|
||||
const xmlIndex = resultString.indexOf('xml:');
|
||||
const externalDocsIndex = resultString.indexOf('externalDocs:');
|
||||
const deprecatedIndex = resultString.indexOf('deprecated:');
|
||||
|
||||
// Test the core ordering - just the most important keys
|
||||
expect(titleIndex).toBeLessThan(descriptionIndex);
|
||||
@@ -242,8 +247,8 @@ describe('Key Ordering Tests', () => {
|
||||
|
||||
describe('Response key ordering', () => {
|
||||
it('should sort response keys correctly', () => {
|
||||
const jsonPrinter = plugin.printers?.['openapi-json-ast'];
|
||||
expect(jsonPrinter).toBeDefined();
|
||||
const printer = plugin.printers?.['openapi-ast'];
|
||||
expect(printer).toBeDefined();
|
||||
|
||||
const testData = {
|
||||
content: {
|
||||
@@ -266,18 +271,20 @@ describe('Key Ordering Tests', () => {
|
||||
}
|
||||
};
|
||||
// @ts-expect-error We are mocking things here so we don't need to pass a print function
|
||||
const result = jsonPrinter?.print({ getValue: () => testData }, { tabWidth: 2 });
|
||||
const result = printer?.print({ getValue: () => testData }, { tabWidth: 2 });
|
||||
expect(result).toBeDefined();
|
||||
|
||||
if (!result) {
|
||||
throw new Error('Result is undefined');
|
||||
}
|
||||
|
||||
const resultString = result.toString();
|
||||
|
||||
// Check that response keys appear in the correct order
|
||||
const descriptionIndex = result.toString().indexOf('"description"');
|
||||
const headersIndex = result.toString().indexOf('"headers"');
|
||||
const contentIndex = result.toString().indexOf('"content"');
|
||||
const linksIndex = result.toString().indexOf('"links"');
|
||||
const descriptionIndex = resultString.indexOf('description');
|
||||
const headersIndex = resultString.indexOf('headers');
|
||||
const contentIndex = resultString.indexOf('content');
|
||||
const linksIndex = resultString.indexOf('links');
|
||||
|
||||
expect(descriptionIndex).toBeLessThan(headersIndex);
|
||||
expect(headersIndex).toBeLessThan(contentIndex);
|
||||
@@ -287,8 +294,8 @@ describe('Key Ordering Tests', () => {
|
||||
|
||||
describe('Parameter key ordering', () => {
|
||||
it('should sort parameter keys correctly', () => {
|
||||
const jsonPrinter = plugin.printers?.['openapi-json-ast'];
|
||||
expect(jsonPrinter).toBeDefined();
|
||||
const printer = plugin.printers?.['openapi-ast'];
|
||||
expect(printer).toBeDefined();
|
||||
|
||||
const testData = {
|
||||
content: {
|
||||
@@ -320,32 +327,27 @@ describe('Key Ordering Tests', () => {
|
||||
}
|
||||
};
|
||||
// @ts-expect-error We are mocking things here so we don't need to pass a print function
|
||||
const result = jsonPrinter?.print({ getValue: () => testData }, { tabWidth: 2 });
|
||||
const result = printer?.print({ getValue: () => testData }, { tabWidth: 2 });
|
||||
expect(result).toBeDefined();
|
||||
|
||||
if (!result) {
|
||||
throw new Error('Result is undefined');
|
||||
}
|
||||
|
||||
// Check that parameter keys appear in the correct order
|
||||
// Find the parameter section specifically (first parameter in the array)
|
||||
const paramStart = result.toString().indexOf('{', result.toString().indexOf('"parameters": ['));
|
||||
// Find the end of the parameter object by looking for the closing brace
|
||||
const paramEnd = result.toString().indexOf('}', result.toString().lastIndexOf('"example"'));
|
||||
const paramSection = result.toString().substring(paramStart, paramEnd + 1);
|
||||
const resultString = result.toString();
|
||||
|
||||
const nameIndex = paramSection.indexOf('"name"');
|
||||
const inIndex = paramSection.indexOf('"in"');
|
||||
const descriptionIndex = paramSection.indexOf('"description"');
|
||||
const requiredIndex = paramSection.indexOf('"required"');
|
||||
const deprecatedIndex = paramSection.indexOf('"deprecated"');
|
||||
const allowEmptyValueIndex = paramSection.indexOf('"allowEmptyValue"');
|
||||
const styleIndex = paramSection.indexOf('"style"');
|
||||
const explodeIndex = paramSection.indexOf('"explode"');
|
||||
const allowReservedIndex = paramSection.indexOf('"allowReserved"');
|
||||
const schemaIndex = paramSection.indexOf('"schema"');
|
||||
const exampleIndex = paramSection.indexOf('"example"');
|
||||
const examplesIndex = paramSection.indexOf('"examples"');
|
||||
const nameIndex = resultString.indexOf('name:');
|
||||
const inIndex = resultString.indexOf('in:');
|
||||
const descriptionIndex = resultString.indexOf('description:');
|
||||
const requiredIndex = resultString.indexOf('required:');
|
||||
const deprecatedIndex = resultString.indexOf('deprecated:');
|
||||
const allowEmptyValueIndex = resultString.indexOf('allowEmptyValue:');
|
||||
const styleIndex = resultString.indexOf('style:');
|
||||
const explodeIndex = resultString.indexOf('explode:');
|
||||
const allowReservedIndex = resultString.indexOf('allowReserved:');
|
||||
const schemaIndex = resultString.indexOf('schema:');
|
||||
const exampleIndex = resultString.indexOf('example:');
|
||||
const examplesIndex = resultString.indexOf('examples:');
|
||||
|
||||
// Test the core parameter ordering
|
||||
expect(nameIndex).toBeLessThan(descriptionIndex);
|
||||
@@ -364,8 +366,8 @@ describe('Key Ordering Tests', () => {
|
||||
|
||||
describe('Security scheme key ordering', () => {
|
||||
it('should sort security scheme keys correctly', () => {
|
||||
const jsonPrinter = plugin.printers?.['openapi-json-ast'];
|
||||
expect(jsonPrinter).toBeDefined();
|
||||
const printer = plugin.printers?.['openapi-ast'];
|
||||
expect(printer).toBeDefined();
|
||||
|
||||
const testData = {
|
||||
content: {
|
||||
@@ -393,22 +395,24 @@ describe('Key Ordering Tests', () => {
|
||||
}
|
||||
};
|
||||
// @ts-expect-error We are mocking things here so we don't need to pass a print function
|
||||
const result = jsonPrinter?.print({ getValue: () => testData }, { tabWidth: 2 });
|
||||
const result = printer?.print({ getValue: () => testData }, { tabWidth: 2 });
|
||||
expect(result).toBeDefined();
|
||||
|
||||
if (!result) {
|
||||
throw new Error('Result is undefined');
|
||||
}
|
||||
|
||||
const resultString = result.toString();
|
||||
|
||||
// Check that security scheme keys appear in the correct order
|
||||
const typeIndex = result.toString().indexOf('"type"');
|
||||
const descriptionIndex = result.toString().indexOf('"description"');
|
||||
const nameIndex = result.toString().indexOf('"name"');
|
||||
const inIndex = result.toString().indexOf('"in"');
|
||||
const schemeIndex = result.toString().indexOf('"scheme"');
|
||||
const bearerFormatIndex = result.toString().indexOf('"bearerFormat"');
|
||||
const flowsIndex = result.toString().indexOf('"flows"');
|
||||
const openIdConnectUrlIndex = result.toString().indexOf('"openIdConnectUrl"');
|
||||
const typeIndex = resultString.indexOf('type:');
|
||||
const descriptionIndex = resultString.indexOf('description:');
|
||||
const nameIndex = resultString.indexOf('name:');
|
||||
const inIndex = resultString.indexOf('in:');
|
||||
const schemeIndex = resultString.indexOf('scheme:');
|
||||
const bearerFormatIndex = resultString.indexOf('bearerFormat:');
|
||||
const flowsIndex = resultString.indexOf('flows:');
|
||||
const openIdConnectUrlIndex = resultString.indexOf('openIdConnectUrl:');
|
||||
|
||||
expect(nameIndex).toBeLessThan(descriptionIndex);
|
||||
expect(descriptionIndex).toBeLessThan(typeIndex);
|
||||
@@ -422,8 +426,8 @@ describe('Key Ordering Tests', () => {
|
||||
|
||||
describe('Server key ordering', () => {
|
||||
it('should sort server keys correctly', () => {
|
||||
const jsonPrinter = plugin.printers?.['openapi-json-ast'];
|
||||
expect(jsonPrinter).toBeDefined();
|
||||
const printer = plugin.printers?.['openapi-ast'];
|
||||
expect(printer).toBeDefined();
|
||||
|
||||
const testData = {
|
||||
content: {
|
||||
@@ -439,24 +443,19 @@ describe('Key Ordering Tests', () => {
|
||||
}
|
||||
};
|
||||
// @ts-expect-error We are mocking things here so we don't need to pass a print function
|
||||
const result = jsonPrinter?.print({ getValue: () => testData }, { tabWidth: 2 });
|
||||
const result = printer?.print({ getValue: () => testData }, { tabWidth: 2 });
|
||||
expect(result).toBeDefined();
|
||||
|
||||
if (!result) {
|
||||
throw new Error('Result is undefined');
|
||||
}
|
||||
|
||||
// Check that server keys appear in the correct order
|
||||
// Find the server section specifically (first server in the array)
|
||||
const serverStart = result.toString().indexOf('{', result.toString().indexOf('"servers": ['));
|
||||
// Find the end of the server object
|
||||
const serverEnd = result.toString().indexOf('}', result.toString().lastIndexOf('"variables"'));
|
||||
const serverSection = result.toString().substring(serverStart, serverEnd + 1);
|
||||
const resultString = result.toString();
|
||||
|
||||
const nameIndex = serverSection.indexOf('"name"');
|
||||
const descriptionIndex = serverSection.indexOf('"description"');
|
||||
const urlIndex = serverSection.indexOf('"url"');
|
||||
const variablesIndex = serverSection.indexOf('"variables"');
|
||||
const nameIndex = resultString.indexOf('name');
|
||||
const descriptionIndex = resultString.indexOf('description');
|
||||
const urlIndex = resultString.indexOf('url');
|
||||
const variablesIndex = resultString.indexOf('variables');
|
||||
|
||||
expect(nameIndex).toBeLessThan(descriptionIndex);
|
||||
expect(descriptionIndex).toBeLessThan(urlIndex);
|
||||
@@ -466,8 +465,8 @@ describe('Key Ordering Tests', () => {
|
||||
|
||||
describe('Tag key ordering', () => {
|
||||
it('should sort tag keys correctly', () => {
|
||||
const jsonPrinter = plugin.printers?.['openapi-json-ast'];
|
||||
expect(jsonPrinter).toBeDefined();
|
||||
const printer = plugin.printers?.['openapi-ast'];
|
||||
expect(printer).toBeDefined();
|
||||
|
||||
const testData = {
|
||||
content: {
|
||||
@@ -483,23 +482,18 @@ describe('Key Ordering Tests', () => {
|
||||
}
|
||||
};
|
||||
// @ts-expect-error We are mocking things here so we don't need to pass a print function
|
||||
const result = jsonPrinter?.print({ getValue: () => testData }, { tabWidth: 2 });
|
||||
const result = printer?.print({ getValue: () => testData }, { tabWidth: 2 });
|
||||
expect(result).toBeDefined();
|
||||
|
||||
if (!result) {
|
||||
throw new Error('Result is undefined');
|
||||
}
|
||||
|
||||
// Check that tag keys appear in the correct order
|
||||
// Find the tag section specifically (first tag in the array)
|
||||
const tagStart = result.toString().indexOf('{', result.toString().indexOf('"tags": ['));
|
||||
// Find the end of the tag object
|
||||
const tagEnd = result.toString().indexOf('}', result.toString().lastIndexOf('"externalDocs"'));
|
||||
const tagSection = result.toString().substring(tagStart, tagEnd + 1);
|
||||
const resultString = result.toString();
|
||||
|
||||
const nameIndex = tagSection.indexOf('"name"');
|
||||
const descriptionIndex = tagSection.indexOf('"description"');
|
||||
const externalDocsIndex = tagSection.indexOf('"externalDocs"');
|
||||
const nameIndex = resultString.indexOf('name');
|
||||
const descriptionIndex = resultString.indexOf('description');
|
||||
const externalDocsIndex = resultString.indexOf('externalDocs');
|
||||
|
||||
expect(nameIndex).toBeLessThan(descriptionIndex);
|
||||
expect(descriptionIndex).toBeLessThan(externalDocsIndex);
|
||||
@@ -508,8 +502,8 @@ describe('Key Ordering Tests', () => {
|
||||
|
||||
describe('External docs key ordering', () => {
|
||||
it('should sort external docs keys correctly', () => {
|
||||
const jsonPrinter = plugin.printers?.['openapi-json-ast'];
|
||||
expect(jsonPrinter).toBeDefined();
|
||||
const printer = plugin.printers?.['openapi-ast'];
|
||||
expect(printer).toBeDefined();
|
||||
|
||||
const testData = {
|
||||
content: {
|
||||
@@ -522,16 +516,18 @@ describe('Key Ordering Tests', () => {
|
||||
}
|
||||
};
|
||||
// @ts-expect-error We are mocking things here so we don't need to pass a print function
|
||||
const result = jsonPrinter?.print({ getValue: () => testData }, { tabWidth: 2 });
|
||||
const result = printer?.print({ getValue: () => testData }, { tabWidth: 2 });
|
||||
expect(result).toBeDefined();
|
||||
|
||||
if (!result) {
|
||||
throw new Error('Result is undefined');
|
||||
}
|
||||
|
||||
const resultString = result.toString();
|
||||
|
||||
// Check that external docs keys appear in the correct order
|
||||
const descriptionIndex = result.toString().indexOf('"description"');
|
||||
const urlIndex = result.toString().indexOf('"url"');
|
||||
const descriptionIndex = resultString.indexOf('description');
|
||||
const urlIndex = resultString.indexOf('url');
|
||||
|
||||
expect(descriptionIndex).toBeLessThan(urlIndex);
|
||||
});
|
||||
@@ -539,8 +535,8 @@ describe('Key Ordering Tests', () => {
|
||||
|
||||
describe('Path sorting', () => {
|
||||
it('should sort paths by specificity', () => {
|
||||
const jsonPrinter = plugin.printers?.['openapi-json-ast'];
|
||||
expect(jsonPrinter).toBeDefined();
|
||||
const printer = plugin.printers?.['openapi-ast'];
|
||||
expect(printer).toBeDefined();
|
||||
|
||||
const testData = {
|
||||
content: {
|
||||
@@ -555,18 +551,20 @@ describe('Key Ordering Tests', () => {
|
||||
}
|
||||
};
|
||||
// @ts-expect-error We are mocking things here so we don't need to pass a print function
|
||||
const result = jsonPrinter?.print({ getValue: () => testData }, { tabWidth: 2 });
|
||||
const result = printer?.print({ getValue: () => testData }, { tabWidth: 2 });
|
||||
expect(result).toBeDefined();
|
||||
|
||||
if (!result) {
|
||||
throw new Error('Result is undefined');
|
||||
}
|
||||
|
||||
const resultString = result.toString();
|
||||
|
||||
// Check that paths are sorted by specificity (fewer parameters first)
|
||||
const usersIndex = result.toString().indexOf('"/users"');
|
||||
const usersIdIndex = result.toString().indexOf('"/users/{id}"');
|
||||
const usersIdPostsIndex = result.toString().indexOf('"/users/{id}/posts"');
|
||||
const usersIdPostsPostIdIndex = result.toString().indexOf('"/users/{id}/posts/{postId}"');
|
||||
const usersIndex = resultString.indexOf('/users');
|
||||
const usersIdIndex = resultString.indexOf('/users/{id}');
|
||||
const usersIdPostsIndex = resultString.indexOf('/users/{id}/posts');
|
||||
const usersIdPostsPostIdIndex = resultString.indexOf('/users/{id}/posts/{postId}');
|
||||
|
||||
expect(usersIndex).toBeLessThan(usersIdIndex);
|
||||
expect(usersIdIndex).toBeLessThan(usersIdPostsIndex);
|
||||
@@ -576,8 +574,8 @@ describe('Key Ordering Tests', () => {
|
||||
|
||||
describe('Response code sorting', () => {
|
||||
it('should sort response codes numerically', () => {
|
||||
const jsonPrinter = plugin.printers?.['openapi-json-ast'];
|
||||
expect(jsonPrinter).toBeDefined();
|
||||
const printer = plugin.printers?.['openapi-ast'];
|
||||
expect(printer).toBeDefined();
|
||||
|
||||
const testData = {
|
||||
content: {
|
||||
@@ -599,19 +597,21 @@ describe('Key Ordering Tests', () => {
|
||||
}
|
||||
};
|
||||
// @ts-expect-error We are mocking things here so we don't need to pass a print function
|
||||
const result = jsonPrinter?.print({ getValue: () => testData }, { tabWidth: 2 });
|
||||
const result = printer?.print({ getValue: () => testData }, { tabWidth: 2 });
|
||||
expect(result).toBeDefined();
|
||||
|
||||
if (!result) {
|
||||
throw new Error('Result is undefined');
|
||||
}
|
||||
|
||||
const resultString = result.toString();
|
||||
|
||||
// Check that response codes are sorted numerically
|
||||
const code200Index = result.toString().indexOf('"200"');
|
||||
const code400Index = result.toString().indexOf('"400"');
|
||||
const code404Index = result.toString().indexOf('"404"');
|
||||
const code500Index = result.toString().indexOf('"500"');
|
||||
const defaultIndex = result.toString().indexOf('"default"');
|
||||
const code200Index = resultString.indexOf('200');
|
||||
const code400Index = resultString.indexOf('400');
|
||||
const code404Index = resultString.indexOf('404');
|
||||
const code500Index = resultString.indexOf('500');
|
||||
const defaultIndex = resultString.indexOf('default');
|
||||
|
||||
expect(code200Index).toBeLessThan(code400Index);
|
||||
expect(code400Index).toBeLessThan(code404Index);
|
||||
|
||||
@@ -12,10 +12,10 @@ describe('Plugin Options', () => {
|
||||
paths: {}
|
||||
};
|
||||
|
||||
const jsonPrinter = plugin.printers?.['openapi-json-ast'];
|
||||
expect(jsonPrinter).toBeDefined();
|
||||
const printer = plugin.printers?.['openapi-ast'];
|
||||
expect(printer).toBeDefined();
|
||||
|
||||
const result = jsonPrinter?.print({ getValue: () => ({ type: 'openapi-json', content: testData, originalText: '' }) }, { tabWidth: 4 }, () => '');
|
||||
const result = printer?.print({ getValue: () => ({ type: 'openapi', content: testData, originalText: '', format: 'json' }) }, { tabWidth: 4 }, () => '');
|
||||
expect(result).toBeDefined();
|
||||
|
||||
if (!result) {
|
||||
@@ -39,10 +39,10 @@ describe('Plugin Options', () => {
|
||||
paths: {}
|
||||
};
|
||||
|
||||
const yamlPrinter = plugin.printers?.['openapi-yaml-ast'];
|
||||
expect(yamlPrinter).toBeDefined();
|
||||
const printer = plugin.printers?.['openapi-ast'];
|
||||
expect(printer).toBeDefined();
|
||||
|
||||
const result = yamlPrinter?.print({ getValue: () => ({ type: 'openapi-yaml', content: testData, originalText: '' }) }, { tabWidth: 4 }, () => '');
|
||||
const result = printer?.print({ getValue: () => ({ type: 'openapi', content: testData, originalText: '', format: 'yaml' }) }, { tabWidth: 4 }, () => '');
|
||||
expect(result).toBeDefined();
|
||||
|
||||
if (!result) {
|
||||
@@ -64,10 +64,10 @@ describe('Plugin Options', () => {
|
||||
paths: {}
|
||||
};
|
||||
|
||||
const jsonPrinter = plugin.printers?.['openapi-json-ast'];
|
||||
expect(jsonPrinter).toBeDefined();
|
||||
const printer = plugin.printers?.['openapi-ast'];
|
||||
expect(printer).toBeDefined();
|
||||
|
||||
const result = jsonPrinter?.print({ getValue: () => ({ type: 'openapi-json', content: testData, originalText: '' }) }, {}, () => '');
|
||||
const result = printer?.print({ getValue: () => ({ type: 'openapi', content: testData, originalText: '', format: 'json' }) }, {}, () => '');
|
||||
expect(result).toBeDefined();
|
||||
|
||||
if (!result) {
|
||||
@@ -91,10 +91,10 @@ describe('Plugin Options', () => {
|
||||
paths: {}
|
||||
};
|
||||
|
||||
const yamlPrinter = plugin.printers?.['openapi-yaml-ast'];
|
||||
expect(yamlPrinter).toBeDefined();
|
||||
const printer = plugin.printers?.['openapi-ast'];
|
||||
expect(printer).toBeDefined();
|
||||
|
||||
const result = yamlPrinter?.print({ getValue: () => ({ type: 'openapi-yaml', content: testData, originalText: '' }) }, { printWidth: 20 }, () => '');
|
||||
const result = printer?.print({ getValue: () => ({ type: 'openapi', content: testData, originalText: '', format: 'yaml' }) }, { printWidth: 20 }, () => '');
|
||||
expect(result).toBeDefined();
|
||||
|
||||
// The YAML should be formatted with the custom line width
|
||||
|
||||
@@ -3,11 +3,11 @@ import plugin from '../dist/index.js';
|
||||
|
||||
describe('Prettier OpenAPI Plugin', () => {
|
||||
it('should format OpenAPI JSON files', () => {
|
||||
const jsonParser = plugin.parsers?.['openapi-json-parser'];
|
||||
const jsonPrinter = plugin.printers?.['openapi-json-ast'];
|
||||
const parser = plugin.parsers?.['openapi-parser'];
|
||||
const printer = plugin.printers?.['openapi-ast'];
|
||||
|
||||
expect(jsonParser).toBeDefined();
|
||||
expect(jsonPrinter).toBeDefined();
|
||||
expect(parser).toBeDefined();
|
||||
expect(printer).toBeDefined();
|
||||
|
||||
const inputJson = `{
|
||||
"paths": {
|
||||
@@ -30,14 +30,15 @@ describe('Prettier OpenAPI Plugin', () => {
|
||||
|
||||
// Parse the JSON
|
||||
// @ts-expect-error We are mocking things here
|
||||
const parsed = jsonParser?.parse(inputJson, {});
|
||||
const parsed = parser?.parse(inputJson, { filepath: 'test.json' });
|
||||
expect(parsed).toBeDefined();
|
||||
expect(parsed?.type).toBe('openapi-json');
|
||||
expect(parsed?.type).toBe('openapi');
|
||||
expect(parsed?.format).toBe('json');
|
||||
expect(parsed?.content).toBeDefined();
|
||||
|
||||
// Format the parsed content
|
||||
// @ts-expect-error We are mocking things here
|
||||
const result = jsonPrinter?.print({ getValue: () => parsed }, { tabWidth: 2 }, () => '');
|
||||
const result = printer?.print({ getValue: () => parsed }, { tabWidth: 2 }, () => '');
|
||||
|
||||
expect(result).toBeDefined();
|
||||
expect(result).toContain('"openapi"');
|
||||
@@ -58,11 +59,11 @@ describe('Prettier OpenAPI Plugin', () => {
|
||||
});
|
||||
|
||||
it('should format OpenAPI YAML files', () => {
|
||||
const yamlParser = plugin.parsers?.['openapi-yaml-parser'];
|
||||
const yamlPrinter = plugin.printers?.['openapi-yaml-ast'];
|
||||
const parser = plugin.parsers?.['openapi-parser'];
|
||||
const printer = plugin.printers?.['openapi-ast'];
|
||||
|
||||
expect(yamlParser).toBeDefined();
|
||||
expect(yamlPrinter).toBeDefined();
|
||||
expect(parser).toBeDefined();
|
||||
expect(printer).toBeDefined();
|
||||
|
||||
const inputYaml = `paths:
|
||||
/test:
|
||||
@@ -77,14 +78,15 @@ openapi: 3.0.0`;
|
||||
|
||||
// Parse the YAML
|
||||
// @ts-expect-error We are mocking things here
|
||||
const parsed = yamlParser?.parse(inputYaml, {});
|
||||
const parsed = parser?.parse(inputYaml, { filepath: 'test.yaml' });
|
||||
expect(parsed).toBeDefined();
|
||||
expect(parsed?.type).toBe('openapi-yaml');
|
||||
expect(parsed?.type).toBe('openapi');
|
||||
expect(parsed?.format).toBe('yaml');
|
||||
expect(parsed?.content).toBeDefined();
|
||||
|
||||
// Format the parsed content
|
||||
// @ts-expect-error We are mocking things here
|
||||
const result = yamlPrinter?.print({ getValue: () => parsed }, { tabWidth: 2 }, () => '');
|
||||
const result = printer?.print({ getValue: () => parsed }, { tabWidth: 2 }, () => '');
|
||||
|
||||
expect(result).toBeDefined();
|
||||
expect(result).toContain('openapi:');
|
||||
@@ -112,11 +114,11 @@ openapi: 3.0.0`;
|
||||
});
|
||||
|
||||
it('should format Swagger 2.0 JSON files', () => {
|
||||
const jsonParser = plugin.parsers?.['openapi-json-parser'];
|
||||
const jsonPrinter = plugin.printers?.['openapi-json-ast'];
|
||||
const parser = plugin.parsers?.['openapi-parser'];
|
||||
const printer = plugin.printers?.['openapi-ast'];
|
||||
|
||||
expect(jsonParser).toBeDefined();
|
||||
expect(jsonPrinter).toBeDefined();
|
||||
expect(parser).toBeDefined();
|
||||
expect(printer).toBeDefined();
|
||||
|
||||
const inputJson = `{
|
||||
"paths": {
|
||||
@@ -144,14 +146,15 @@ openapi: 3.0.0`;
|
||||
|
||||
// Parse the JSON
|
||||
// @ts-expect-error We are mocking things here
|
||||
const parsed = jsonParser?.parse(inputJson, {});
|
||||
const parsed = parser?.parse(inputJson, { filepath: 'test.json' });
|
||||
expect(parsed).toBeDefined();
|
||||
expect(parsed?.type).toBe('openapi-json');
|
||||
expect(parsed?.type).toBe('openapi');
|
||||
expect(parsed?.format).toBe('json');
|
||||
expect(parsed?.content).toBeDefined();
|
||||
|
||||
// Format the parsed content
|
||||
// @ts-expect-error We are mocking things here
|
||||
const result = jsonPrinter?.print({ getValue: () => parsed }, { tabWidth: 2 }, () => '');
|
||||
const result = printer?.print({ getValue: () => parsed }, { tabWidth: 2 }, () => '');
|
||||
|
||||
expect(result).toBeDefined();
|
||||
expect(result).toContain('"swagger"');
|
||||
@@ -178,11 +181,11 @@ openapi: 3.0.0`;
|
||||
describe('Key Ordering Tests', () => {
|
||||
describe('Top-level key ordering', () => {
|
||||
it('should sort OpenAPI 3.0+ keys correctly', () => {
|
||||
const jsonParser = plugin.parsers?.['openapi-json-parser'];
|
||||
const jsonPrinter = plugin.printers?.['openapi-json-ast'];
|
||||
const parser = plugin.parsers?.['openapi-parser'];
|
||||
const printer = plugin.printers?.['openapi-ast'];
|
||||
|
||||
expect(jsonParser).toBeDefined();
|
||||
expect(jsonPrinter).toBeDefined();
|
||||
expect(parser).toBeDefined();
|
||||
expect(printer).toBeDefined();
|
||||
|
||||
const inputJson = `{
|
||||
"paths": { "/test": { "get": {} } },
|
||||
@@ -196,14 +199,15 @@ describe('Key Ordering Tests', () => {
|
||||
|
||||
// Parse the JSON
|
||||
// @ts-expect-error We are mocking things here
|
||||
const parsed = jsonParser?.parse(inputJson, {});
|
||||
const parsed = parser?.parse(inputJson, { filepath: 'test.json' });
|
||||
expect(parsed).toBeDefined();
|
||||
expect(parsed?.type).toBe('openapi-json');
|
||||
expect(parsed?.type).toBe('openapi');
|
||||
expect(parsed?.format).toBe('json');
|
||||
expect(parsed?.content).toBeDefined();
|
||||
|
||||
// Format the parsed content
|
||||
// @ts-expect-error We are mocking things here
|
||||
const result = jsonPrinter?.print({ getValue: () => parsed }, { tabWidth: 2 }, () => '');
|
||||
const result = printer?.print({ getValue: () => parsed }, { tabWidth: 2 }, () => '');
|
||||
|
||||
expect(result).toBeDefined();
|
||||
|
||||
@@ -229,11 +233,11 @@ describe('Key Ordering Tests', () => {
|
||||
});
|
||||
|
||||
it('should sort Swagger 2.0 keys correctly', () => {
|
||||
const jsonParser = plugin.parsers?.['openapi-json-parser'];
|
||||
const jsonPrinter = plugin.printers?.['openapi-json-ast'];
|
||||
const parser = plugin.parsers?.['openapi-parser'];
|
||||
const printer = plugin.printers?.['openapi-ast'];
|
||||
|
||||
expect(jsonParser).toBeDefined();
|
||||
expect(jsonPrinter).toBeDefined();
|
||||
expect(parser).toBeDefined();
|
||||
expect(printer).toBeDefined();
|
||||
|
||||
const inputJson = `{
|
||||
"paths": { "/test": { "get": {} } },
|
||||
@@ -255,14 +259,15 @@ describe('Key Ordering Tests', () => {
|
||||
|
||||
// Parse the JSON
|
||||
// @ts-expect-error We are mocking things here
|
||||
const parsed = jsonParser?.parse(inputJson, {});
|
||||
const parsed = parser?.parse(inputJson, { filepath: 'test.json' });
|
||||
expect(parsed).toBeDefined();
|
||||
expect(parsed?.type).toBe('openapi-json');
|
||||
expect(parsed?.type).toBe('openapi');
|
||||
expect(parsed?.format).toBe('json');
|
||||
expect(parsed?.content).toBeDefined();
|
||||
|
||||
// Format the parsed content
|
||||
// @ts-expect-error We are mocking things here
|
||||
const result = jsonPrinter?.print({ getValue: () => parsed }, { tabWidth: 2 }, () => '');
|
||||
const result = printer?.print({ getValue: () => parsed }, { tabWidth: 2 }, () => '');
|
||||
|
||||
expect(result).toBeDefined();
|
||||
|
||||
|
||||
@@ -3,8 +3,8 @@ import plugin from '../src/index';
|
||||
|
||||
describe('Simple Key Ordering Tests', () => {
|
||||
it('should sort top-level OpenAPI keys correctly', () => {
|
||||
const jsonPrinter = plugin.printers?.['openapi-json-ast'];
|
||||
expect(jsonPrinter).toBeDefined();
|
||||
const printer = plugin.printers?.['openapi-ast'];
|
||||
expect(printer).toBeDefined();
|
||||
|
||||
const testData = {
|
||||
content: {
|
||||
@@ -19,21 +19,23 @@ describe('Simple Key Ordering Tests', () => {
|
||||
};
|
||||
|
||||
// @ts-expect-error We are mocking things here
|
||||
const result = jsonPrinter?.print({ getValue: () => testData }, { tabWidth: 2 }, () => '');
|
||||
const result = printer?.print({ getValue: () => testData }, { tabWidth: 2 }, () => '');
|
||||
expect(result).toBeDefined();
|
||||
|
||||
if (!result) {
|
||||
throw new Error('Result is undefined');
|
||||
}
|
||||
|
||||
const resultString = result.toString();
|
||||
|
||||
// Check that keys appear in the correct order
|
||||
const openapiIndex = result.toString().indexOf('"openapi"');
|
||||
const infoIndex = result.toString().indexOf('"info"');
|
||||
const externalDocsIndex = result.toString().indexOf('"externalDocs"');
|
||||
const securityIndex = result.toString().indexOf('"security"');
|
||||
const tagsIndex = result.toString().indexOf('"tags"');
|
||||
const pathsIndex = result.toString().indexOf('"paths"');
|
||||
const componentsIndex = result.toString().indexOf('"components"');
|
||||
const openapiIndex = resultString.indexOf('openapi');
|
||||
const infoIndex = resultString.indexOf('info');
|
||||
const externalDocsIndex = resultString.indexOf('externalDocs');
|
||||
const securityIndex = resultString.indexOf('security');
|
||||
const tagsIndex = resultString.indexOf('tags');
|
||||
const pathsIndex = resultString.indexOf('paths');
|
||||
const componentsIndex = resultString.indexOf('components');
|
||||
|
||||
expect(openapiIndex).toBeLessThan(infoIndex);
|
||||
expect(infoIndex).toBeLessThan(externalDocsIndex);
|
||||
@@ -44,8 +46,8 @@ describe('Simple Key Ordering Tests', () => {
|
||||
});
|
||||
|
||||
it('should sort operation keys correctly', () => {
|
||||
const jsonPrinter = plugin.printers?.['openapi-json-ast'];
|
||||
expect(jsonPrinter).toBeDefined();
|
||||
const printer = plugin.printers?.['openapi-ast'];
|
||||
expect(printer).toBeDefined();
|
||||
|
||||
const testData = {
|
||||
content: {
|
||||
@@ -72,25 +74,27 @@ describe('Simple Key Ordering Tests', () => {
|
||||
};
|
||||
|
||||
// @ts-expect-error We are mocking things here
|
||||
const result = jsonPrinter?.print({ getValue: () => testData }, { tabWidth: 2 }, () => '');
|
||||
const result = printer?.print({ getValue: () => testData }, { tabWidth: 2 }, () => '');
|
||||
expect(result).toBeDefined();
|
||||
|
||||
if (!result) {
|
||||
throw new Error('Result is undefined');
|
||||
}
|
||||
|
||||
const resultString = result.toString();
|
||||
|
||||
// Check that operation keys appear in the correct order
|
||||
const summaryIndex = result.toString().indexOf('"summary"');
|
||||
const operationIdIndex = result.toString().indexOf('"operationId"');
|
||||
const descriptionIndex = result.toString().indexOf('"description"');
|
||||
const tagsIndex = result.toString().indexOf('"tags"');
|
||||
const deprecatedIndex = result.toString().indexOf('"deprecated"');
|
||||
const securityIndex = result.toString().indexOf('"security"');
|
||||
const serversIndex = result.toString().indexOf('"servers"');
|
||||
const parametersIndex = result.toString().indexOf('"parameters"');
|
||||
const requestBodyIndex = result.toString().indexOf('"requestBody"');
|
||||
const responsesIndex = result.toString().indexOf('"responses"');
|
||||
const callbacksIndex = result.toString().indexOf('"callbacks"');
|
||||
const summaryIndex = resultString.indexOf('summary');
|
||||
const operationIdIndex = resultString.indexOf('operationId');
|
||||
const descriptionIndex = resultString.indexOf('description');
|
||||
const tagsIndex = resultString.indexOf('tags');
|
||||
const deprecatedIndex = resultString.indexOf('deprecated');
|
||||
const securityIndex = resultString.indexOf('security');
|
||||
const serversIndex = resultString.indexOf('servers');
|
||||
const parametersIndex = resultString.indexOf('parameters');
|
||||
const requestBodyIndex = resultString.indexOf('requestBody');
|
||||
const responsesIndex = resultString.indexOf('responses');
|
||||
const callbacksIndex = resultString.indexOf('callbacks');
|
||||
|
||||
expect(summaryIndex).toBeLessThan(operationIdIndex);
|
||||
expect(operationIdIndex).toBeLessThan(descriptionIndex);
|
||||
@@ -105,8 +109,8 @@ describe('Simple Key Ordering Tests', () => {
|
||||
});
|
||||
|
||||
it('should sort info keys correctly', () => {
|
||||
const jsonPrinter = plugin.printers?.['openapi-json-ast'];
|
||||
expect(jsonPrinter).toBeDefined();
|
||||
const printer = plugin.printers?.['openapi-ast'];
|
||||
expect(printer).toBeDefined();
|
||||
|
||||
const testData = {
|
||||
content: {
|
||||
@@ -123,20 +127,24 @@ describe('Simple Key Ordering Tests', () => {
|
||||
};
|
||||
|
||||
// @ts-expect-error We are mocking things here
|
||||
const result = jsonPrinter?.print({ getValue: () => testData }, { tabWidth: 2 }, () => '');
|
||||
const result = printer?.print({ getValue: () => testData }, { tabWidth: 2 }, () => '');
|
||||
expect(result).toBeDefined();
|
||||
|
||||
if (!result) {
|
||||
throw new Error('Result is undefined');
|
||||
}
|
||||
|
||||
const resultString = result.toString();
|
||||
|
||||
console.log(resultString);
|
||||
|
||||
// Check that info keys appear in the correct order
|
||||
const titleIndex = result.toString().indexOf('"title"');
|
||||
const versionIndex = result.toString().indexOf('"version"');
|
||||
const descriptionIndex = result.toString().indexOf('"description"');
|
||||
const termsOfServiceIndex = result.toString().indexOf('"termsOfService"');
|
||||
const contactIndex = result.toString().indexOf('"contact"');
|
||||
const licenseIndex = result.toString().indexOf('"license"');
|
||||
const titleIndex = resultString.indexOf('title');
|
||||
const versionIndex = resultString.indexOf('version');
|
||||
const descriptionIndex = resultString.indexOf('description');
|
||||
const termsOfServiceIndex = resultString.indexOf('termsOfService');
|
||||
const contactIndex = resultString.indexOf('contact');
|
||||
const licenseIndex = resultString.indexOf('license');
|
||||
|
||||
expect(titleIndex).toBeLessThan(versionIndex);
|
||||
expect(versionIndex).toBeLessThan(descriptionIndex);
|
||||
@@ -146,8 +154,8 @@ describe('Simple Key Ordering Tests', () => {
|
||||
});
|
||||
|
||||
it('should handle custom extensions correctly', () => {
|
||||
const jsonPrinter = plugin.printers?.['openapi-json-ast'];
|
||||
expect(jsonPrinter).toBeDefined();
|
||||
const printer = plugin.printers?.['openapi-ast'];
|
||||
expect(printer).toBeDefined();
|
||||
|
||||
const testData = {
|
||||
content: {
|
||||
@@ -160,7 +168,7 @@ describe('Simple Key Ordering Tests', () => {
|
||||
};
|
||||
|
||||
// @ts-expect-error We are mocking things here
|
||||
const result = jsonPrinter?.print({ getValue: () => testData }, { tabWidth: 2 }, () => '');
|
||||
const result = printer?.print({ getValue: () => testData }, { tabWidth: 2 }, () => '');
|
||||
expect(result).toBeDefined();
|
||||
|
||||
if (!result) {
|
||||
@@ -168,11 +176,11 @@ describe('Simple Key Ordering Tests', () => {
|
||||
}
|
||||
|
||||
// Custom extensions should come after standard keys
|
||||
const openapiIndex = result.toString().indexOf('"openapi"');
|
||||
const infoIndex = result.toString().indexOf('"info"');
|
||||
const pathsIndex = result.toString().indexOf('"paths"');
|
||||
const xCustomFieldIndex = result.toString().indexOf('"x-custom-field"');
|
||||
const xMetadataIndex = result.toString().indexOf('"x-metadata"');
|
||||
const openapiIndex = result.toString().indexOf('openapi');
|
||||
const infoIndex = result.toString().indexOf('info');
|
||||
const pathsIndex = result.toString().indexOf('paths');
|
||||
const xCustomFieldIndex = result.toString().indexOf('x-custom-field');
|
||||
const xMetadataIndex = result.toString().indexOf('x-metadata');
|
||||
|
||||
expect(openapiIndex).toBeLessThan(infoIndex);
|
||||
expect(infoIndex).toBeLessThan(pathsIndex);
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ESNext",
|
||||
"target": "ES2020",
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "node",
|
||||
"lib": ["ESNext"],
|
||||
"lib": ["ES2022"],
|
||||
"outDir": "./dist",
|
||||
"rootDir": "./src",
|
||||
"strict": true,
|
||||
|
||||
Reference in New Issue
Block a user