snapshot of https://github.com/mountain-loop/yaak.git (main, 2026-09-23; blobs > 131072B omitted)
Some checks failed
Lint and Test / Lint/Test (push) Has been cancelled
Generate Sponsors README / deploy (push) Has been skipped

This commit is contained in:
upstream-mirror
2026-09-23 17:39:41 +05:00
commit 906fb231cc
1544 changed files with 164131 additions and 0 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,819 @@
openapi: 3.0.2
servers:
- url: /v3
info:
description: |-
This is a sample Pet Store Server based on the OpenAPI 3.0 specification. You can find out more about
Swagger at [http://swagger.io](http://swagger.io). In the third iteration of the pet store, we've switched to the design first approach!
You can now help us improve the API whether it's by making changes to the definition itself or to the code.
That way, with time, we can improve the API in general, and expose some of the new features in OAS3.
Some useful links:
- [The Pet Store repository](https://github.com/swagger-api/swagger-petstore)
- [The source API definition for the Pet Store](https://github.com/swagger-api/swagger-petstore/blob/master/src/main/resources/openapi.yaml)
version: 1.0.20-SNAPSHOT
title: Swagger Petstore - OpenAPI 3.0
termsOfService: "http://swagger.io/terms/"
contact:
email: apiteam@swagger.io
license:
name: Apache 2.0
url: "http://www.apache.org/licenses/LICENSE-2.0.html"
tags:
- name: pet
description: Everything about your Pets
externalDocs:
description: Find out more
url: "http://swagger.io"
- name: store
description: Access to Petstore orders
externalDocs:
description: Find out more about our store
url: "http://swagger.io"
- name: user
description: Operations about user
paths:
/pet:
post:
tags:
- pet
summary: Add a new pet to the store
description: Add a new pet to the store
operationId: addPet
responses:
"200":
description: Successful operation
content:
application/xml:
schema:
$ref: "#/components/schemas/Pet"
application/json:
schema:
$ref: "#/components/schemas/Pet"
"405":
description: Invalid input
security:
- petstore_auth:
- "write:pets"
- "read:pets"
requestBody:
description: Create a new pet in the store
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/Pet"
application/xml:
schema:
$ref: "#/components/schemas/Pet"
application/x-www-form-urlencoded:
schema:
$ref: "#/components/schemas/Pet"
put:
tags:
- pet
summary: Update an existing pet
description: Update an existing pet by Id
operationId: updatePet
responses:
"200":
description: Successful operation
content:
application/xml:
schema:
$ref: "#/components/schemas/Pet"
application/json:
schema:
$ref: "#/components/schemas/Pet"
"400":
description: Invalid ID supplied
"404":
description: Pet not found
"405":
description: Validation exception
security:
- petstore_auth:
- "write:pets"
- "read:pets"
requestBody:
description: Update an existent pet in the store
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/Pet"
application/xml:
schema:
$ref: "#/components/schemas/Pet"
application/x-www-form-urlencoded:
schema:
$ref: "#/components/schemas/Pet"
/pet/findByStatus:
get:
tags:
- pet
summary: Finds Pets by status
description: Multiple status values can be provided with comma separated strings
operationId: findPetsByStatus
parameters:
- name: status
in: query
description: Status values that need to be considered for filter
required: false
explode: true
schema:
type: string
enum:
- available
- pending
- sold
default: available
responses:
"200":
description: successful operation
content:
application/xml:
schema:
type: array
items:
$ref: "#/components/schemas/Pet"
application/json:
schema:
type: array
items:
$ref: "#/components/schemas/Pet"
"400":
description: Invalid status value
security:
- petstore_auth:
- "write:pets"
- "read:pets"
/pet/findByTags:
get:
tags:
- pet
summary: Finds Pets by tags
description: >-
Multiple tags can be provided with comma separated strings. Use tag1,
tag2, tag3 for testing.
operationId: findPetsByTags
parameters:
- name: tags
in: query
description: Tags to filter by
required: false
explode: true
schema:
type: array
items:
type: string
responses:
"200":
description: successful operation
content:
application/xml:
schema:
type: array
items:
$ref: "#/components/schemas/Pet"
application/json:
schema:
type: array
items:
$ref: "#/components/schemas/Pet"
"400":
description: Invalid tag value
security:
- petstore_auth:
- "write:pets"
- "read:pets"
"/pet/{petId}":
get:
tags:
- pet
summary: Find pet by ID
description: Returns a single pet
operationId: getPetById
parameters:
- name: petId
in: path
description: ID of pet to return
required: true
schema:
type: integer
format: int64
responses:
"200":
description: successful operation
content:
application/xml:
schema:
$ref: "#/components/schemas/Pet"
application/json:
schema:
$ref: "#/components/schemas/Pet"
"400":
description: Invalid ID supplied
"404":
description: Pet not found
security:
- api_key: []
- petstore_auth:
- "write:pets"
- "read:pets"
post:
tags:
- pet
summary: Updates a pet in the store with form data
description: ""
operationId: updatePetWithForm
parameters:
- name: petId
in: path
description: ID of pet that needs to be updated
required: true
schema:
type: integer
format: int64
- name: name
in: query
description: Name of pet that needs to be updated
schema:
type: string
- name: status
in: query
description: Status of pet that needs to be updated
schema:
type: string
responses:
"405":
description: Invalid input
security:
- petstore_auth:
- "write:pets"
- "read:pets"
delete:
tags:
- pet
summary: Deletes a pet
description: ""
operationId: deletePet
parameters:
- name: api_key
in: header
description: ""
required: false
schema:
type: string
- name: petId
in: path
description: Pet id to delete
required: true
schema:
type: integer
format: int64
responses:
"400":
description: Invalid pet value
security:
- petstore_auth:
- "write:pets"
- "read:pets"
"/pet/{petId}/uploadImage":
post:
tags:
- pet
summary: uploads an image
description: ""
operationId: uploadFile
parameters:
- name: petId
in: path
description: ID of pet to update
required: true
schema:
type: integer
format: int64
- name: additionalMetadata
in: query
description: Additional Metadata
required: false
schema:
type: string
responses:
"200":
description: successful operation
content:
application/json:
schema:
$ref: "#/components/schemas/ApiResponse"
security:
- petstore_auth:
- "write:pets"
- "read:pets"
requestBody:
content:
application/octet-stream:
schema:
type: string
format: binary
/store/inventory:
get:
tags:
- store
summary: Returns pet inventories by status
description: Returns a map of status codes to quantities
operationId: getInventory
x-swagger-router-controller: OrderController
responses:
"200":
description: successful operation
content:
application/json:
schema:
type: object
additionalProperties:
type: integer
format: int32
security:
- api_key: []
/store/order:
post:
tags:
- store
summary: Place an order for a pet
description: Place a new order in the store
operationId: placeOrder
x-swagger-router-controller: OrderController
responses:
"200":
description: successful operation
content:
application/json:
schema:
$ref: "#/components/schemas/Order"
"405":
description: Invalid input
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/Order"
application/xml:
schema:
$ref: "#/components/schemas/Order"
application/x-www-form-urlencoded:
schema:
$ref: "#/components/schemas/Order"
"/store/order/{orderId}":
get:
tags:
- store
summary: Find purchase order by ID
x-swagger-router-controller: OrderController
description: >-
For valid response try integer IDs with value <= 5 or > 10. Other values
will generate exceptions.
operationId: getOrderById
parameters:
- name: orderId
in: path
description: ID of order that needs to be fetched
required: true
schema:
type: integer
format: int64
responses:
"200":
description: successful operation
content:
application/xml:
schema:
$ref: "#/components/schemas/Order"
application/json:
schema:
$ref: "#/components/schemas/Order"
"400":
description: Invalid ID supplied
"404":
description: Order not found
delete:
tags:
- store
summary: Delete purchase order by ID
x-swagger-router-controller: OrderController
description: >-
For valid response try integer IDs with value < 1000. Anything above
1000 or nonintegers will generate API errors
operationId: deleteOrder
parameters:
- name: orderId
in: path
description: ID of the order that needs to be deleted
required: true
schema:
type: integer
format: int64
responses:
"400":
description: Invalid ID supplied
"404":
description: Order not found
/user:
post:
tags:
- user
summary: Create user
description: This can only be done by the logged in user.
operationId: createUser
responses:
default:
description: successful operation
content:
application/json:
schema:
$ref: "#/components/schemas/User"
application/xml:
schema:
$ref: "#/components/schemas/User"
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/User"
application/xml:
schema:
$ref: "#/components/schemas/User"
application/x-www-form-urlencoded:
schema:
$ref: "#/components/schemas/User"
description: Created user object
/user/createWithList:
post:
tags:
- user
summary: Creates list of users with given input array
description: "Creates list of users with given input array"
x-swagger-router-controller: UserController
operationId: createUsersWithListInput
responses:
"200":
description: Successful operation
content:
application/xml:
schema:
$ref: "#/components/schemas/User"
application/json:
schema:
$ref: "#/components/schemas/User"
default:
description: successful operation
requestBody:
content:
application/json:
schema:
type: array
items:
$ref: "#/components/schemas/User"
/user/login:
get:
tags:
- user
summary: Logs user into the system
description: ""
operationId: loginUser
parameters:
- name: username
in: query
description: The user name for login
required: false
schema:
type: string
- name: password
in: query
description: The password for login in clear text
required: false
schema:
type: string
responses:
"200":
description: successful operation
headers:
X-Rate-Limit:
description: calls per hour allowed by the user
schema:
type: integer
format: int32
X-Expires-After:
description: date in UTC when token expires
schema:
type: string
format: date-time
content:
application/xml:
schema:
type: string
application/json:
schema:
type: string
"400":
description: Invalid username/password supplied
/user/logout:
get:
tags:
- user
summary: Logs out current logged in user session
description: ""
operationId: logoutUser
parameters: []
responses:
default:
description: successful operation
"/user/{username}":
get:
tags:
- user
summary: Get user by user name
description: ""
operationId: getUserByName
parameters:
- name: username
in: path
description: "The name that needs to be fetched. Use user1 for testing. "
required: true
schema:
type: string
responses:
"200":
description: successful operation
content:
application/xml:
schema:
$ref: "#/components/schemas/User"
application/json:
schema:
$ref: "#/components/schemas/User"
"400":
description: Invalid username supplied
"404":
description: User not found
put:
tags:
- user
summary: Update user
x-swagger-router-controller: UserController
description: This can only be done by the logged in user.
operationId: updateUser
parameters:
- name: username
in: path
description: name that needs to be updated
required: true
schema:
type: string
responses:
default:
description: successful operation
requestBody:
description: Update an existent user in the store
content:
application/json:
schema:
$ref: "#/components/schemas/User"
application/xml:
schema:
$ref: "#/components/schemas/User"
application/x-www-form-urlencoded:
schema:
$ref: "#/components/schemas/User"
delete:
tags:
- user
summary: Delete user
description: This can only be done by the logged in user.
operationId: deleteUser
parameters:
- name: username
in: path
description: The name that needs to be deleted
required: true
schema:
type: string
responses:
"400":
description: Invalid username supplied
"404":
description: User not found
externalDocs:
description: Find out more about Swagger
url: "http://swagger.io"
components:
schemas:
Order:
x-swagger-router-model: io.swagger.petstore.model.Order
properties:
id:
type: integer
format: int64
example: 10
petId:
type: integer
format: int64
example: 198772
quantity:
type: integer
format: int32
example: 7
shipDate:
type: string
format: date-time
status:
type: string
description: Order Status
enum:
- placed
- approved
- delivered
example: approved
complete:
type: boolean
xml:
name: order
type: object
Customer:
properties:
id:
type: integer
format: int64
example: 100000
username:
type: string
example: fehguy
address:
type: array
items:
$ref: "#/components/schemas/Address"
xml:
wrapped: true
name: addresses
xml:
name: customer
type: object
Address:
properties:
street:
type: string
example: 437 Lytton
city:
type: string
example: Palo Alto
state:
type: string
example: CA
zip:
type: string
example: 94301
xml:
name: address
type: object
Category:
x-swagger-router-model: io.swagger.petstore.model.Category
properties:
id:
type: integer
format: int64
example: 1
name:
type: string
example: Dogs
xml:
name: category
type: object
User:
x-swagger-router-model: io.swagger.petstore.model.User
properties:
id:
type: integer
format: int64
example: 10
username:
type: string
example: theUser
firstName:
type: string
example: John
lastName:
type: string
example: James
email:
type: string
example: john@email.com
password:
type: string
example: 12345
phone:
type: string
example: 12345
userStatus:
type: integer
format: int32
example: 1
description: User Status
xml:
name: user
type: object
Tag:
x-swagger-router-model: io.swagger.petstore.model.Tag
properties:
id:
type: integer
format: int64
name:
type: string
xml:
name: tag
type: object
Pet:
x-swagger-router-model: io.swagger.petstore.model.Pet
required:
- name
- photoUrls
properties:
id:
type: integer
format: int64
example: 10
name:
type: string
example: doggie
category:
$ref: "#/components/schemas/Category"
photoUrls:
type: array
xml:
wrapped: true
items:
type: string
xml:
name: photoUrl
tags:
type: array
xml:
wrapped: true
items:
$ref: "#/components/schemas/Tag"
xml:
name: tag
status:
type: string
description: pet status in the store
enum:
- available
- pending
- sold
xml:
name: pet
type: object
ApiResponse:
properties:
code:
type: integer
format: int32
type:
type: string
message:
type: string
xml:
name: "##default"
type: object
requestBodies:
Pet:
content:
application/json:
schema:
$ref: "#/components/schemas/Pet"
application/xml:
schema:
$ref: "#/components/schemas/Pet"
description: Pet object that needs to be added to the store
UserArray:
content:
application/json:
schema:
type: array
items:
$ref: "#/components/schemas/User"
description: List of user object
securitySchemes:
petstore_auth:
type: oauth2
flows:
implicit:
authorizationUrl: "https://petstore.swagger.io/oauth/authorize"
scopes:
"write:pets": modify pets in your account
"read:pets": read your pets
api_key:
type: apiKey
name: api_key
in: header

View File

@@ -0,0 +1,8 @@
# Real-World OpenAPI Fixtures
These fixtures were copied from the public APIs.guru OpenAPI directory:
- `apis-guru.yaml`: https://api.apis.guru/v2/specs/apis.guru/2.2.0/openapi.yaml
- `httpbin.yaml`: https://api.apis.guru/v2/specs/httpbin.org/0.9.2/openapi.yaml
- `nasa-apod.yaml`: https://api.apis.guru/v2/specs/nasa.gov/apod/1.0.0/openapi.yaml
- `xkcd.yaml`: https://api.apis.guru/v2/specs/xkcd.com/1.0.0/openapi.yaml

View File

@@ -0,0 +1,399 @@
openapi: 3.0.0
servers:
- url: https://api.apis.guru/v2
info:
contact:
email: mike.ralphson@gmail.com
name: APIs.guru
url: https://APIs.guru
description: |
Wikipedia for Web APIs. Repository of API definitions in OpenAPI format.
**Warning**: If you want to be notified about changes in advance please join our [Slack channel](https://join.slack.com/t/mermade/shared_invite/zt-g78g7xir-MLE_CTCcXCdfJfG3CJe9qA).
Client sample: [[Demo]](https://apis.guru/simple-ui) [[Repo]](https://github.com/APIs-guru/simple-ui)
license:
name: CC0 1.0
url: https://github.com/APIs-guru/openapi-directory#licenses
title: APIs.guru
version: 2.2.0
x-apisguru-categories:
- open_data
- developer_tools
x-logo:
url: https://api.apis.guru/v2/cache/logo/https_apis.guru_branding_logo_vertical.svg
x-origin:
- format: openapi
url: https://api.apis.guru/v2/openapi.yaml
version: "3.0"
x-providerName: apis.guru
x-tags:
- API
- Catalog
- Directory
- REST
- Swagger
- OpenAPI
externalDocs:
url: https://github.com/APIs-guru/openapi-directory/blob/master/API.md
security: []
tags:
- description: Actions relating to APIs in the collection
name: APIs
paths:
/list.json:
get:
description: |
List all APIs in the directory.
Returns links to the OpenAPI definitions for each API in the directory.
If API exist in multiple versions `preferred` one is explicitly marked.
Some basic info from the OpenAPI definition is cached inside each object.
This allows you to generate some simple views without needing to fetch the OpenAPI definition for each API.
operationId: listAPIs
responses:
"200":
content:
application/json:
schema:
$ref: "#/components/schemas/APIs"
description: OK
summary: List all APIs
tags:
- APIs
/metrics.json:
get:
description: |
Some basic metrics for the entire directory.
Just stunning numbers to put on a front page and are intended purely for WoW effect :)
operationId: getMetrics
responses:
"200":
content:
application/json:
schema:
$ref: "#/components/schemas/Metrics"
description: OK
summary: Get basic metrics
tags:
- APIs
/providers.json:
get:
description: |
List all the providers in the directory
operationId: getProviders
responses:
"200":
content:
application/json:
schema:
properties:
data:
items:
minLength: 1
type: string
minItems: 1
type: array
type: object
description: OK
summary: List all providers
tags:
- APIs
"/specs/{provider}/{api}.json":
get:
description: Returns the API entry for one specific version of an API where there is no serviceName.
operationId: getAPI
parameters:
- $ref: "#/components/parameters/provider"
- $ref: "#/components/parameters/api"
responses:
"200":
content:
application/json:
schema:
$ref: "#/components/schemas/API"
description: OK
summary: Retrieve one version of a particular API
tags:
- APIs
"/specs/{provider}/{service}/{api}.json":
get:
description: Returns the API entry for one specific version of an API where there is a serviceName.
operationId: getServiceAPI
parameters:
- $ref: "#/components/parameters/provider"
- in: path
name: service
required: true
schema:
example: graph
maxLength: 255
minLength: 1
type: string
- $ref: "#/components/parameters/api"
responses:
"200":
content:
application/json:
schema:
$ref: "#/components/schemas/API"
description: OK
summary: Retrieve one version of a particular API with a serviceName.
tags:
- APIs
"/{provider}.json":
get:
description: |
List all APIs in the directory for a particular providerName
Returns links to the individual API entry for each API.
operationId: getProvider
parameters:
- $ref: "#/components/parameters/provider"
responses:
"200":
content:
application/json:
schema:
$ref: "#/components/schemas/APIs"
description: OK
summary: List all APIs for a particular provider
tags:
- APIs
"/{provider}/services.json":
get:
description: |
List all serviceNames in the directory for a particular providerName
operationId: getServices
parameters:
- $ref: "#/components/parameters/provider"
responses:
"200":
content:
application/json:
schema:
properties:
data:
items:
minLength: 0
type: string
minItems: 1
type: array
type: object
description: OK
summary: List all serviceNames for a particular provider
tags:
- APIs
components:
parameters:
api:
in: path
name: api
required: true
schema:
example: 2.1.0
maxLength: 255
minLength: 1
type: string
provider:
in: path
name: provider
required: true
schema:
example: apis.guru
maxLength: 255
minLength: 1
type: string
schemas:
API:
additionalProperties: false
description: Meta information about API
properties:
added:
description: Timestamp when the API was first added to the directory
format: date-time
type: string
preferred:
description: Recommended version
type: string
versions:
additionalProperties:
$ref: "#/components/schemas/ApiVersion"
description: List of supported versions of the API
minProperties: 1
type: object
required:
- added
- preferred
- versions
type: object
APIs:
additionalProperties:
$ref: "#/components/schemas/API"
description: |
List of API details.
It is a JSON object with API IDs(`<provider>[:<service>]`) as keys.
example:
googleapis.com:drive:
added: 2015-02-22T20:00:45.000Z
preferred: v3
versions:
v2:
added: 2015-02-22T20:00:45.000Z
info:
title: Drive
version: v2
x-apiClientRegistration:
url: https://console.developers.google.com
x-logo:
url: https://api.apis.guru/v2/cache/logo/https_www.gstatic.com_images_icons_material_product_2x_drive_32dp.png
x-origin:
format: google
url: https://www.googleapis.com/discovery/v1/apis/drive/v2/rest
version: v1
x-preferred: false
x-providerName: googleapis.com
x-serviceName: drive
swaggerUrl: https://api.apis.guru/v2/specs/googleapis.com/drive/v2/swagger.json
swaggerYamlUrl: https://api.apis.guru/v2/specs/googleapis.com/drive/v2/swagger.yaml
updated: 2016-06-17T00:21:44.000Z
v3:
added: 2015-12-12T00:25:13.000Z
info:
title: Drive
version: v3
x-apiClientRegistration:
url: https://console.developers.google.com
x-logo:
url: https://api.apis.guru/v2/cache/logo/https_www.gstatic.com_images_icons_material_product_2x_drive_32dp.png
x-origin:
format: google
url: https://www.googleapis.com/discovery/v1/apis/drive/v3/rest
version: v1
x-preferred: true
x-providerName: googleapis.com
x-serviceName: drive
swaggerUrl: https://api.apis.guru/v2/specs/googleapis.com/drive/v3/swagger.json
swaggerYamlUrl: https://api.apis.guru/v2/specs/googleapis.com/drive/v3/swagger.yaml
updated: 2016-06-17T00:21:44.000Z
minProperties: 1
type: object
ApiVersion:
additionalProperties: false
properties:
added:
description: Timestamp when the version was added
format: date-time
type: string
externalDocs:
description: Copy of `externalDocs` section from OpenAPI definition
minProperties: 1
type: object
info:
description: Copy of `info` section from OpenAPI definition
minProperties: 1
type: object
link:
description: Link to the individual API entry for this API
format: url
type: string
openapiVer:
description: The value of the `openapi` or `swagger` property of the source definition
type: string
swaggerUrl:
description: URL to OpenAPI definition in JSON format
format: url
type: string
swaggerYamlUrl:
description: URL to OpenAPI definition in YAML format
format: url
type: string
updated:
description: Timestamp when the version was updated
format: date-time
type: string
required:
- added
- updated
- swaggerUrl
- swaggerYamlUrl
- info
- openapiVer
type: object
Metrics:
additionalProperties: false
description: List of basic metrics
example:
datasets: []
fixedPct: 22
fixes: 81119
invalid: 598
issues: 28
numAPIs: 2501
numDrivers: 10
numEndpoints: 106448
numProviders: 659
numSpecs: 3329
stars: 2429
thisWeek:
added: 45
updated: 171
unofficial: 25
unreachable: 123
properties:
datasets:
description: Data used for charting etc
items: {}
type: array
fixedPct:
description: Percentage of all APIs where auto fixes have been applied
type: integer
fixes:
description: Total number of fixes applied across all APIs
type: integer
invalid:
description: Number of newly invalid APIs
type: integer
issues:
description: Open GitHub issues on our main repo
type: integer
numAPIs:
description: Number of unique APIs
minimum: 1
type: integer
numDrivers:
description: Number of methods of API retrieval
type: integer
numEndpoints:
description: Total number of endpoints inside all definitions
minimum: 1
type: integer
numProviders:
description: Number of API providers in directory
type: integer
numSpecs:
description: Number of API definitions including different versions of the same API
minimum: 1
type: integer
stars:
description: GitHub stars for our main repo
type: integer
thisWeek:
description: Summary totals for the last 7 days
properties:
added:
description: APIs added in the last week
type: integer
updated:
description: APIs updated in the last week
type: integer
type: object
unofficial:
description: Number of unofficial APIs
type: integer
unreachable:
description: Number of unreachable (4XX,5XX status) APIs
type: integer
required:
- numSpecs
- numAPIs
- numEndpoints
type: object
x-optic-standard: "@febf8ac6-ee67-4565-b45a-5c85a469dca7/Fz6KU3_wMIO5iJ6_VUZ30"
x-optic-url: https://app.useoptic.com/organizations/febf8ac6-ee67-4565-b45a-5c85a469dca7/apis/_0fKWqUvhs9ssYNkq1k-c

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,69 @@
openapi: 3.0.0
servers:
- url: https://api.nasa.gov/planetary
- url: http://api.nasa.gov/planetary
info:
contact:
email: evan.t.yates@nasa.gov
description: This endpoint structures the APOD imagery and associated metadata so that it can be repurposed for other applications. In addition, if the concept_tags parameter is set to True, then keywords derived from the image explanation are returned. These keywords could be used as auto-generated hashtags for twitter or instagram feeds; but generally help with discoverability of relevant imagery
license:
name: Apache 2.0
url: http://www.apache.org/licenses/LICENSE-2.0.html
title: APOD
version: 1.0.0
x-apisguru-categories:
- media
- open_data
x-origin:
- format: swagger
url: https://raw.githubusercontent.com/nasa/api-docs/gh-pages/assets/json/APOD
version: "2.0"
x-providerName: nasa.gov
x-serviceName: apod
x-logo:
url: https://api.apis.guru/v2/cache/logo/https_apis.guru_assets_images_no-logo.svg
tags:
- description: An example tag
externalDocs:
description: Here's a link
url: https://example.com
name: request tag
paths:
/apod:
get:
description: Returns the picture of the day
parameters:
- description: The date of the APOD image to retrieve
in: query
name: date
required: false
schema:
type: string
- description: Retrieve the URL for the high resolution image
in: query
name: hd
required: false
schema:
type: boolean
responses:
"200":
content:
application/json:
schema:
items:
x-thing: ok
type: array
description: successful operation
"400":
description: Date must be between Jun 16, 1995 and Mar 28, 2019.
security:
- api_key: []
summary: Returns images
tags:
- request tag
components:
securitySchemes:
api_key:
in: query
name: api_key
type: apiKey

View File

@@ -0,0 +1,78 @@
openapi: 3.0.0
servers:
- url: http://xkcd.com/
info:
description: Webcomic of romance, sarcasm, math, and language.
title: XKCD
version: 1.0.0
x-apisguru-categories:
- media
x-logo:
url: https://api.apis.guru/v2/cache/logo/http_imgs.xkcd.com_static_terrible_small_logo.png
x-origin:
- format: openapi
url: https://raw.githubusercontent.com/APIs-guru/unofficial_openapi_specs/master/xkcd.com/1.0.0/openapi.yaml
version: "3.0"
x-providerName: xkcd.com
x-tags:
- humor
- comics
x-unofficialSpec: true
externalDocs:
url: https://xkcd.com/json.html
paths:
/info.0.json:
get:
description: |
Fetch current comic and metadata.
responses:
"200":
content:
"*/*":
schema:
$ref: "#/components/schemas/comic"
description: OK
"/{comicId}/info.0.json":
get:
description: |
Fetch comics and metadata by comic id.
parameters:
- in: path
name: comicId
required: true
schema:
type: number
responses:
"200":
content:
"*/*":
schema:
$ref: "#/components/schemas/comic"
description: OK
components:
schemas:
comic:
properties:
alt:
type: string
day:
type: string
img:
type: string
link:
type: string
month:
type: string
news:
type: string
num:
type: number
safe_title:
type: string
title:
type: string
transcript:
type: string
year:
type: string
type: object

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,306 @@
// Round-trip harness: import a spec with the local importer plugin, send every
// request through the real Yaak CLI pipeline against a Prism mock of the same
// spec, and report Prism's validation verdict for each request.
//
// Prism independently validates each incoming request against the spec (paths,
// required parameters, body schemas, security), so a violation here is an
// importer bug found by a second OpenAPI implementation rather than a snapshot
// of our own output.
//
// Usage: node tests/roundtrip.mjs [spec.yaml ...]
// YAAK_BIN=/path/to/yaak overrides the CLI (defaults to the repo debug build,
// which embeds the plugins vendored from this checkout).
import { execFileSync, spawn } from "node:child_process";
import * as fs from "node:fs";
import * as os from "node:os";
import * as path from "node:path";
import { fileURLToPath } from "node:url";
const here = path.dirname(fileURLToPath(import.meta.url));
const repoRoot = path.resolve(here, "../../..");
const yaakBin = process.env.YAAK_BIN ?? path.join(repoRoot, "target/debug/yaak");
const specs =
process.argv.length > 2
? process.argv.slice(2)
: [
path.join(here, "fixtures/petstore.yaml"),
...fs
.readdirSync(path.join(here, "fixtures/real-world"))
.filter((f) => f.endsWith(".yaml"))
.map((f) => path.join(here, "fixtures/real-world", f)),
];
if (!fs.existsSync(yaakBin)) {
console.error(`Yaak CLI not found at ${yaakBin}. Build it with: cargo build -p yaak-cli`);
process.exit(2);
}
// Pinned so local runs and CI judge against the same validator
const PRISM_PACKAGE = "@stoplight/prism-cli@5.15.11";
// Accepted spec-quality gray zones, not importer bugs. httpbin's required
// `url` query parameter has no example, and an empty value is preferable to
// inventing fake query data even though Prism counts it as missing.
const KNOWN_FLAGS = new Set(["httpbin.yaml GET ${[baseUrl]}/redirect-to"]);
function yaak(dataDir, args) {
return execFileSync(yaakBin, ["--data-dir", dataDir, ...args], {
encoding: "utf-8",
stdio: ["ignore", "pipe", "pipe"],
});
}
function yaakJson(dataDir, args) {
return JSON.parse(yaak(dataDir, args));
}
function listIds(output) {
return output
.split("\n")
.map((line) => line.match(/^(\w+_\w+) - /)?.[1])
.filter(Boolean);
}
async function startPrism(spec, port) {
for (let attempt = 0; attempt < 20; attempt++, port++) {
const prism = spawn(
"npx",
["-y", PRISM_PACKAGE, "mock", "--errors", "-p", String(port), "-h", "127.0.0.1", spec],
{ stdio: ["ignore", "pipe", "pipe"] },
);
let log = "";
prism.stdout.on("data", (d) => (log += d));
prism.stderr.on("data", (d) => (log += d));
// Generous: the first run downloads Prism through npx
const deadline = Date.now() + 120_000;
let failed = false;
while (Date.now() < deadline) {
if (log.includes("Prism is listening")) return { prism, port, getLog: () => log };
if (log.includes("EADDRINUSE") || prism.exitCode != null) {
failed = true;
break;
}
await new Promise((r) => setTimeout(r, 200));
}
prism.kill();
if (failed) {
// The exit can be observed before its buffered stderr arrives; wait for
// the streams to close so the bind error is distinguishable
await Promise.race([
new Promise((r) => prism.once("close", r)),
new Promise((r) => setTimeout(r, 2000)),
]);
if (log.includes("EADDRINUSE")) continue;
throw new Error(`Prism exited:\n${log}`);
}
throw new Error(`Prism did not start in time:\n${log}`);
}
throw new Error("No free port found for Prism");
}
function pointVariablesAtPrism(variables, prismUrl) {
return variables.map((v) => {
if (v.name === "baseUrl" || v.name.startsWith("serverUrl")) return { ...v, value: prismUrl };
if (v.name === "baseUrlOrigin") return { ...v, value: prismUrl };
if (v.value === "") return { ...v, value: "test-value" };
return v;
});
}
// Prism reports its verdict in the sl-violations response header. Violations
// located in the request are importer bugs; violations located in the response
// mean Prism could not fabricate a spec-valid mock response (the spec's own
// examples are broken), which says nothing about the import.
function classify(response, bodyText) {
if (response.error) return { verdict: "SEND ERROR", detail: response.error };
const violationsHeader = (response.headers ?? []).find(
(h) => h.name?.toLowerCase() === "sl-violations",
);
let violations = [];
try {
violations = JSON.parse(violationsHeader?.value ?? "[]");
} catch {}
const requestViolations = violations.filter((v) => v.location?.[0] === "request");
const detail = requestViolations.map((v) => `${v.location.join(".")}: ${v.message}`).join("; ");
if (requestViolations.length > 0) return { verdict: "VIOLATION", detail };
// A spec-defined error response (e.g. an operation whose only response is a
// 405) mocks as that status with no Prism error type; only Prism's own error
// bodies mark a request Prism could not accept.
let body = null;
try {
body = JSON.parse(bodyText);
} catch {}
const prismError =
typeof body?.type === "string" && body.type.includes("stoplight.io/prism/errors")
? body.type.split("#")[1]
: null;
if (prismError == null) return { verdict: "ok", detail: "" };
// Failures to fabricate a mock response say nothing about the request we sent
if (prismError === "NO_COMPLEX_OBJECT_TEXT" || prismError === "NO_RESPONSE_DEFINED") {
return { verdict: "ok", detail: "" };
}
const bodyViolations = Array.isArray(body.validation)
? body.validation.filter((v) => v.location?.[0] === "request")
: [];
if (prismError === "VIOLATIONS" && bodyViolations.length === 0) {
return { verdict: "ok", detail: "" }; // response-side only
}
return {
verdict:
prismError === "VIOLATIONS" || prismError === "UNPROCESSABLE_ENTITY"
? "VIOLATION"
: prismError.includes("MATCHED")
? "NO ROUTE"
: prismError === "UNAUTHORIZED"
? "SECURITY"
: prismError,
detail:
bodyViolations.map((v) => `${v.location.join(".")}: ${v.message}`).join("; ") ||
body.detail ||
"",
};
}
let totalProblems = 0;
let port = 4010;
for (const spec of specs) {
const name = path.basename(spec);
const dataDir = fs.mkdtempSync(path.join(os.tmpdir(), "yaak-roundtrip-"));
console.log(`\n=== ${name} ===`);
try {
yaak(dataDir, ["import", spec]);
const workspaceId = listIds(yaak(dataDir, ["workspace", "list"]))[0];
if (workspaceId == null) {
console.log(" IMPORT PRODUCED NO WORKSPACE");
totalProblems++;
continue;
}
// Prism mocks redirect responses without a Location header; following them
// would fail the send for a reason unrelated to the import. Workspace-level
// OAuth2 gets the same dummy-bearer treatment as request-level below.
const workspace = yaakJson(dataDir, ["workspace", "show", workspaceId]);
yaak(dataDir, [
"workspace",
"update",
"--json",
JSON.stringify({
id: workspaceId,
settingFollowRedirects: false,
...(workspace.authenticationType === "oauth2"
? {
authenticationType: "bearer",
authentication: { token: "test-token", prefix: "Bearer" },
}
: {}),
}),
]);
const { prism, port: boundPort, getLog } = await startPrism(spec, port);
port = boundPort + 1;
try {
const prismUrl = `http://127.0.0.1:${boundPort}`;
const environmentIds = listIds(yaak(dataDir, ["environment", "list", workspaceId]));
let activeEnvironment = null;
for (const id of environmentIds) {
const environment = yaakJson(dataDir, ["environment", "show", id]);
yaak(dataDir, [
"environment",
"update",
"--json",
JSON.stringify({
id,
variables: pointVariablesAtPrism(environment.variables ?? [], prismUrl),
}),
]);
if (environment.parentModel === "environment" && activeEnvironment == null) {
activeEnvironment = id;
}
}
const requestIds = listIds(yaak(dataDir, ["request", "list", workspaceId]));
const requests = new Map();
for (const id of requestIds) {
const request = yaakJson(dataDir, ["request", "show", id]);
requests.set(id, request);
// OAuth2 would try to fetch a real token; Prism only checks that the
// Authorization header is present, so a dummy bearer keeps it satisfied.
if (request.authenticationType === "oauth2") {
yaak(dataDir, [
"request",
"update",
"--json",
JSON.stringify({
id,
authenticationType: "bearer",
authentication: { token: "test-token", prefix: "Bearer" },
}),
]);
}
}
const sendArgs = ["send", workspaceId];
if (activeEnvironment != null) sendArgs.push("-e", activeEnvironment);
try {
yaak(dataDir, sendArgs);
} catch {
// Individual send failures surface per-request below.
}
let problems = 0;
for (const id of requestIds) {
const request = requests.get(id);
const label = `${request.method} ${request.url}`;
let response = null;
let bodyText = "";
try {
response = yaakJson(dataDir, ["response", "show", id]);
try {
bodyText = yaak(dataDir, ["response", "body", id]);
} catch {}
} catch {
console.log(` NEVER SENT ${label}`);
problems++;
continue;
}
const { verdict, detail } = classify(response, bodyText);
if (verdict === "ok") continue;
if (KNOWN_FLAGS.has(`${name} ${label}`)) {
console.log(` known ${label}`);
continue;
}
problems++;
console.log(` ${verdict.padEnd(12)} ${label}`);
console.log(` sent: ${response.url ?? "?"}`);
if (detail) console.log(` ${detail}`);
}
const requestCount = requestIds.length;
if (problems === 0) {
console.log(` all ${requestCount} requests validated clean against the mock`);
} else {
console.log(` ${problems}/${requestCount} requests flagged`);
totalProblems += problems;
}
const inputWarnings = getLog()
.split("\n")
.filter((l) => l.includes("[VALIDATOR]") && !l.includes("output"));
if (inputWarnings.length > 0) {
console.log(` prism validator log lines: ${inputWarnings.length}`);
}
} finally {
prism.kill();
}
} finally {
fs.rmSync(dataDir, { recursive: true, force: true });
}
}
process.exit(totalProblems > 0 ? 1 : 0);