UNPKG

@ibm-cloud/openapi-ruleset

Version:

Spectral ruleset for validating IBM Cloud services

1,306 lines (1,304 loc) 34.2 kB
/** * Copyright 2017 - 2024 IBM Corporation. * SPDX-License-Identifier: Apache2.0 */ module.exports = { openapi: '3.0.0', info: { title: 'Root Test Definition', description: 'API definition for testing custom Spectral rules.', version: '1.0.0', }, servers: [ { url: 'https://some-madeup-url.com/api', }, ], security: [ { IAM: [], }, { OpenIdScheme: ['openid:admin'], }, ], tags: [ { name: 'TestTag', description: 'A tag used for testing.', }, ], paths: { '/v1/drinks': { post: { operationId: 'create_drink', summary: 'Create a drink', description: 'Create a new Drink instance.', tags: ['TestTag'], security: [ { DrinkScheme: ['mixologist'], }, ], 'x-codegen-request-body-name': 'drink', requestBody: { required: true, content: { 'application/json': { schema: { $ref: '#/components/schemas/DrinkPrototype', }, }, }, }, responses: { 201: { description: 'Success!', content: { 'application/json': { schema: { $ref: '#/components/schemas/Drink', }, }, }, }, 400: { description: 'Error!', content: { 'application/json': { schema: { $ref: '#/components/schemas/ErrorContainer', }, }, }, }, }, }, get: { operationId: 'list_drinks', summary: 'List drinks', description: 'Retrieve all the drinks.', tags: ['TestTag'], security: [ { Basic: [], DrinkScheme: ['drinker'], }, ], parameters: [ { name: 'start', in: 'query', description: 'A token which indicates the first item to return.', required: false, schema: { type: 'string', pattern: '^[a-zA-Z0-9 ]+$', minLength: 1, maxLength: 128, }, }, { name: 'limit', in: 'query', description: 'The number of items to return per page.', required: false, schema: { type: 'integer', format: 'int32', minimum: 1, maximum: 100, default: 10, }, }, ], responses: { 200: { description: 'Success!', content: { 'application/json': { schema: { $ref: '#/components/schemas/DrinkCollection', }, }, }, }, 400: { description: 'Error!', content: { 'application/json': { schema: { $ref: '#/components/schemas/ErrorContainer', }, }, }, }, }, }, }, '/v1/drinks/{drink_id}': { parameters: [ { $ref: '#/components/parameters/DrinkIdParam', }, ], get: { operationId: 'get_drink', summary: 'Have a drink', description: 'Retrieve and consume a refreshing beverage.', tags: ['TestTag'], security: [ { DrinkScheme: [], }, ], parameters: [ { $ref: '#/components/parameters/VerboseParam', }, ], responses: { 200: { $ref: '#/components/responses/ConsumedDrink', }, 400: { $ref: '#/components/responses/BarIsClosed', }, }, }, }, '/v1/drink_menu': { get: { operationId: 'download_drink_menu', summary: 'Download Drinks Menu', description: 'Retrieve a document containing the drinks menu.', tags: ['TestTag'], responses: { 200: { content: { 'application/octet-stream': { schema: { description: 'Document file contents', type: 'string', format: 'binary', minLength: 0, maxLength: 1024000, }, }, }, }, }, }, put: { operationId: 'replace_drink_menu', summary: 'Upload Drinks Menu', description: 'Publish a new Drinks Menu for public viewing.', tags: ['TestTag'], 'x-codegen-request-body-name': 'document', parameters: [ { in: 'query', name: 'document_name', description: 'The document name as a string.', schema: { description: 'Name of the file as a string', type: 'string', pattern: '^[a-z0-9]*.pdf$', minLength: 0, maxLength: 1024000, }, }, { in: 'query', name: 'document_type', description: 'The document type as a string.', content: { 'application/json': { schema: { description: 'valid document types', type: 'string', enum: ['pdf', 'odt', 'doc'], }, }, }, }, ], requestBody: { required: true, content: { 'application/octet-stream': { schema: { description: 'The document contents.', type: 'string', format: 'binary', minLength: 0, maxLength: 1024000, }, }, }, }, responses: { 200: { description: 'Upload confirmed!', content: { 'text/plain': { schema: { description: 'String response for upload request.', type: 'string', minLength: 0, maxLength: 512, pattern: '^[a-zA-Z0-9 ]+$', }, }, }, }, }, }, }, '/v1/movies': { post: { operationId: 'create_movie', summary: 'Create a movie', description: 'Create a new Movie instance.', tags: ['TestTag'], security: [ { MovieScheme: ['director'], }, ], requestBody: { required: true, content: { 'application/json': { schema: { $ref: '#/components/schemas/MoviePrototype', }, }, }, }, responses: { 201: { description: 'Success!', content: { 'application/json': { schema: { $ref: '#/components/schemas/Movie', }, }, }, }, 400: { description: 'Error!', content: { 'application/json': { schema: { $ref: '#/components/schemas/ErrorContainer', }, }, }, }, }, }, get: { operationId: 'list_movies', summary: 'List movies', description: 'Retrieve a list of movies using an optional genre qualifier.', tags: ['TestTag'], security: [ { MovieScheme: ['moviegoer'], }, ], parameters: [ { description: 'An optional genre to filter on.', name: 'genre', required: false, in: 'query', schema: { type: 'string', enum: ['comedy', 'drama', 'action', 'musical', 'documentary'], }, }, { name: 'start', in: 'query', description: 'A token which indicates the first item to return.', required: false, schema: { type: 'string', pattern: '^[a-zA-Z0-9 ]+$', minLength: 1, maxLength: 128, }, }, { name: 'limit', in: 'query', description: 'The number of items to return per page.', required: false, schema: { type: 'integer', format: 'int32', minimum: 1, maximum: 100, default: 10, }, }, ], responses: { 200: { description: 'Success!', content: { 'application/json': { schema: { $ref: '#/components/schemas/MovieCollection', }, example: { limit: 2, total_count: 2, first: { href: 'first page', }, last: { href: 'last page', }, movies: [ { id: '1234', name: 'The Fellowship of the Ring' }, { id: '5678', name: 'The Two Towers' }, ], }, }, }, }, }, }, }, '/v1/movies/{movie_id}': { parameters: [ { $ref: '#/components/parameters/MovieIdParam', }, ], get: { operationId: 'get_movie', summary: 'Get a movie', description: 'Retrieve the movie and return it in the response.', tags: ['TestTag'], security: [ { MovieScheme: ['moviegoer'], }, ], responses: { 200: { $ref: '#/components/responses/MovieWithETag', }, 400: { description: 'Didnt work!', content: { 'application/json': { schema: { $ref: '#/components/schemas/ErrorContainer', }, }, }, }, }, }, put: { operationId: 'replace_movie', summary: 'Replace movie', description: 'Replace a movie with updated state information.', tags: ['TestTag'], parameters: [ { $ref: '#/components/parameters/IfMatchParam', }, ], security: [ { MovieScheme: ['director'], }, ], 'x-codegen-request-body-name': 'movie', requestBody: { required: true, content: { 'application/json': { schema: { $ref: '#/components/schemas/MoviePrototype', }, }, }, }, responses: { 200: { $ref: '#/components/responses/MovieWithETag', }, 400: { description: 'Didnt work!', content: { 'application/json': { schema: { $ref: '#/components/schemas/ErrorContainer', }, }, }, }, 409: { description: 'Resource conflict!', content: { 'application/json': { schema: { $ref: '#/components/schemas/ErrorContainer', }, }, }, }, }, }, }, '/v1/cars': { post: { operationId: 'create_car', summary: 'Create a car', description: 'Create a new Car instance.', tags: ['TestTag'], parameters: [ { $ref: '#/components/parameters/ExpediteParam', }, ], security: [ { IAM: [], }, ], 'x-codegen-request-body-name': 'car', requestBody: { $ref: '#/components/requestBodies/CarRequest', }, responses: { 201: { description: 'The car instance was returned in the response.', content: { 'application/json': { schema: { $ref: '#/components/schemas/Car', }, examples: { ResponseExample: { $ref: '#/components/examples/CarExample', }, }, }, }, links: { CarId: { $ref: '#/components/links/CarIdLink', }, }, }, 400: { $ref: '#/components/responses/ErrorResponse', }, }, }, }, '/v1/cars/{car_id}': { parameters: [ { $ref: '#/components/parameters/CarIdParam', }, ], get: { operationId: 'get_car', summary: 'Get Car', description: 'Retrieve a Car instance by its id.', tags: ['TestTag'], security: [ { IAM: [], }, ], responses: { 200: { $ref: '#/components/responses/CarResponse', }, 400: { $ref: '#/components/responses/ErrorResponse', }, }, }, patch: { operationId: 'update_car', summary: 'Update a car', description: 'Update a new Car instance with new state information.', tags: ['TestTag'], security: [ { IAM: [], }, ], requestBody: { $ref: '#/components/requestBodies/UpdateCarRequest', }, responses: { 200: { description: 'The car instance was updated successfully.', content: { 'application/json': { schema: { $ref: '#/components/schemas/Car', }, examples: { ResponseExample: { $ref: '#/components/examples/CarExample', }, }, }, }, }, 400: { $ref: '#/components/responses/ErrorResponse', }, }, }, }, }, components: { parameters: { DrinkIdParam: { name: 'drink_id', description: 'The id of the drink resource.', in: 'path', required: true, schema: { type: 'string', pattern: '^[a-zA-Z0-9 ]+$', minLength: 1, maxLength: 30, }, }, MovieIdParam: { name: 'movie_id', description: 'The id of the movie resource.', in: 'path', required: true, schema: { type: 'string', pattern: '^[a-zA-Z0-9 ]+$', minLength: 1, maxLength: 30, }, }, VerboseParam: { description: 'An optional verbose parameter.', name: 'verbose', required: false, in: 'query', schema: { type: 'boolean', }, }, ExpediteParam: { description: 'An optional parameter to speed up the car manufacturing process.', name: 'hurry_up', required: false, in: 'query', schema: { type: 'boolean', }, }, CarIdParam: { description: 'A car id.', name: 'car_id', required: true, in: 'path', schema: { type: 'string', pattern: '^[a-zA-Z0-9 ]+$', minLength: 1, maxLength: 30, }, }, IfMatchParam: { description: 'The If-Match header param.', name: 'If-Match', required: true, in: 'header', schema: { type: 'string', pattern: '^[a-zA-Z0-9 ]+$', minLength: 1, maxLength: 64, }, }, }, schemas: { Movie: { description: 'This is the Movie schema.', type: 'object', required: ['id', 'name'], properties: { id: { $ref: '#/components/schemas/IdString', }, name: { $ref: '#/components/schemas/NormalString', }, director: { $ref: '#/components/schemas/NormalString', }, running_time: { type: 'integer', format: 'int32', minimum: 0, maximum: 360, description: 'The length of the movie, in minutes.', }, imdb_url: { $ref: '#/components/schemas/UrlString', }, trailer: { type: 'string', format: 'byte', description: 'A short trailer for the movie.', minLength: 0, maxLength: 1024, }, }, example: { id: 'acb123', name: 'The Two Towers', director: 'Peter Jackson', running_time: 179, }, }, MoviePrototype: { description: 'This is the Movie creation schema.', type: 'object', required: ['name'], properties: { name: { $ref: '#/components/schemas/NormalString', }, director: { $ref: '#/components/schemas/NormalString', }, running_time: { type: 'integer', format: 'int32', minimum: 0, maximum: 360, description: 'The length of the movie, in minutes.', }, imdb_url: { $ref: '#/components/schemas/UrlString', }, trailer: { type: 'string', format: 'byte', description: 'A short trailer for the movie.', minLength: 0, maxLength: 1024, }, }, example: { name: 'The Two Towers', director: 'Peter Jackson', running_time: 179, }, }, Drink: { type: 'object', description: 'A Drink can be either a Juice or Soda instance. Sorry, no Beer or Whisky allowed.', properties: { id: { $ref: '#/components/schemas/IdString', }, }, oneOf: [ { $ref: '#/components/schemas/Juice', }, { $ref: '#/components/schemas/Soda', }, ], discriminator: { propertyName: 'type', }, example: { id: 'acb123', type: 'soda', name: 'Root Beer', }, }, DrinkPrototype: { type: 'object', description: 'A Drink can be either a Juice or Soda instance. Sorry, no Beer or Whisky allowed.', oneOf: [ { $ref: '#/components/schemas/Juice', }, { $ref: '#/components/schemas/Soda', }, ], discriminator: { propertyName: 'type', }, example: { type: 'soda', name: 'Root Beer', }, }, Soda: { description: 'Do you really not know what a Soda is?', type: 'object', required: ['type', 'name'], properties: { type: { description: 'The drink type - should be "soda".', type: 'string', enum: ['soda'], }, name: { $ref: '#/components/schemas/NormalString', }, }, }, Juice: { description: 'Juice box!', type: 'object', required: ['type', 'fruit'], properties: { type: { description: 'The drink type - should be "juice".', type: 'string', enum: ['juice'], }, fruit: { $ref: '#/components/schemas/NormalString', }, }, }, NormalString: { description: 'This is a normal string.', type: 'string', pattern: '^[a-zA-Z0-9 ]+$', minLength: 1, maxLength: 30, }, IdString: { description: 'An identifier of some sort.', type: 'string', readOnly: true, pattern: '^[a-zA-Z0-9]+$', minLength: 1, maxLength: 10, }, UrlString: { description: 'A URL of some sort.', type: 'string', format: 'url', pattern: '^https://.*$', maxLength: 1024, }, DrinkCollection: { type: 'object', description: 'A single page of results containing Drink instances.', allOf: [ { $ref: '#/components/schemas/TokenPaginationBase', }, { type: 'object', required: ['drinks'], properties: { drinks: { description: 'The set of Drink instances in this page of results.', type: 'array', minItems: 0, maxItems: 50, items: { $ref: '#/components/schemas/Drink', }, }, }, }, ], example: { limit: 1, total_count: 1, first: { href: 'first page', }, next: { href: 'next page', }, previous: { href: 'previous page', }, last: { href: 'last page', }, drinks: [ { type: 'soda', name: 'Root Beer', }, ], }, }, MovieCollection: { type: 'object', description: 'A single page of results containing Movie instances.', allOf: [ { $ref: '#/components/schemas/TokenPaginationBase', }, { type: 'object', required: ['movies'], properties: { movies: { description: 'The set of Movie instances in this page of results.', type: 'array', minItems: 0, maxItems: 50, items: { $ref: '#/components/schemas/Movie', }, }, }, }, ], example: { limit: 1, total_count: 1, first: { href: 'first page', }, next: { href: 'next page', }, previous: { href: 'previous page', }, last: { href: 'last page', }, movies: [ { id: 'acb123', name: 'The Two Towers', director: 'Peter Jackson', running_time: 179, }, ], }, }, Car: { description: 'Information about a car.', type: 'object', required: ['id', 'make', 'model'], properties: { id: { description: 'The car id.', type: 'string', minLength: 1, maxLength: 64, pattern: '^[0-9]+$', }, make: { description: 'The car make.', type: 'string', minLength: 1, maxLength: 32, pattern: '^.*$', }, model: { $ref: '#/components/schemas/CarModelType', }, }, }, CarPrototype: { description: 'Information about a car.', type: 'object', required: ['make', 'model'], properties: { make: { description: 'The car make.', type: 'string', minLength: 1, maxLength: 32, pattern: '^.*$', }, model: { $ref: '#/components/schemas/CarModelType', }, }, }, CarPatch: { description: 'Information about a car.', type: 'object', properties: { make: { description: 'The car make.', type: 'string', minLength: 1, maxLength: 32, pattern: '^.*$', }, model: { $ref: '#/components/schemas/CarModelType', }, }, }, CarModelType: { description: 'The car model.', type: 'string', minLength: 1, maxLength: 32, pattern: '^.*$', }, TokenPaginationBase: { description: 'A base schema containing properties that support token-based pagination.', type: 'object', required: ['limit', 'total_count'], properties: { limit: { description: 'The number of items returned in this page of results.', type: 'integer', format: 'int32', minimum: 1, maximum: 100, }, total_count: { description: 'The total number of items across all result pages.', type: 'integer', format: 'int32', minimum: 0, maximum: 1024, }, first: { $ref: '#/components/schemas/PageLink', }, next: { $ref: '#/components/schemas/PageLink', }, previous: { $ref: '#/components/schemas/PageLink', }, last: { allOf: [ { $ref: '#/components/schemas/PageLink', }, { description: 'Link to the last page of results.', }, ], }, }, }, PageLink: { description: 'Contains a link to a page of paginated results', type: 'object', properties: { href: { description: 'The link value', type: 'string', pattern: '^[a-zA-Z0-9 ]+$', minLength: 1, maxLength: 30, }, }, }, ErrorContainer: { description: 'An error response for an operation.', type: 'object', required: ['errors'], properties: { errors: { type: 'array', minItems: 0, maxItems: 100, description: 'The array of error entries associated with the error response', items: { $ref: '#/components/schemas/Error', }, }, status_code: { type: 'integer', format: 'int32', minimum: 0, maximum: 599, description: 'The HTTP status code.', }, trace: { description: 'The error trace information.', type: 'string', format: 'identifier', pattern: '^[a-zA-Z0-9 ]+$', maxLength: 30, }, }, }, Error: { description: 'An error response entry.', type: 'object', required: ['code'], properties: { code: { description: 'The error code.', type: 'string', enum: ['bad_request', 'not_authorized', 'no_need_to_know'], }, message: { description: 'The error message.', type: 'string', pattern: '^[a-zA-Z0-9 ]+$', minLength: 1, maxLength: 128, }, more_info: { description: 'Additional info about the error.', type: 'string', pattern: '^[a-zA-Z0-9 ]+$', minLength: 1, maxLength: 128, }, target: { $ref: '#/components/schemas/ErrorTarget', }, }, }, ErrorTarget: { description: 'An error target (a field, header or query parameter).', type: 'object', required: ['type'], properties: { type: { description: 'The error target type.', type: 'string', enum: ['field', 'header', 'parameter'], }, name: { description: 'The name of the field/header/query parameter associated with the error.', type: 'string', pattern: '^[a-zA-Z0-9 ]+$', minLength: 1, maxLength: 30, }, }, }, }, securitySchemes: { IAM: { type: 'apiKey', description: 'An IAM access token provided via the Authorization header', in: 'header', name: 'Authorization', }, Basic: { type: 'http', description: 'A basic-auth type Authorization header', scheme: 'Basic', bearerFormat: 'bearer', }, DrinkScheme: { type: 'oauth2', description: 'An oauth2 authorizaton flow', flows: { implicit: { authorizationUrl: 'https://myoauthserver.com/auth', tokenUrl: 'https://myoauthserver.com/token', scopes: { mixologist: 'Can create Drinks', drinker: 'Can consume beverages', }, }, authorizationCode: { authorizationUrl: 'https://myoauthserver.com/auth', tokenUrl: 'https://myoauthserver.com/token', scopes: { mixologist: 'Can create Drinks', }, }, }, }, MovieScheme: { type: 'oauth2', description: 'An oauth2 authorizaton flow', flows: { implicit: { authorizationUrl: 'https://myoauthserver.com/auth', tokenUrl: 'https://myoauthserver.com/token', scopes: { director: 'Can create Movies', moviegoer: 'Can view Movies', }, }, authorizationCode: { authorizationUrl: 'https://myoauthserver.com/auth', tokenUrl: 'https://myoauthserver.com/token', scopes: { director: 'Can create Movies', }, }, clientCredentials: { tokenUrl: 'https://myoauthserver.com/token', scopes: { moviegoer: 'Can view Movies', }, }, password: { tokenUrl: 'https://myoauthserver.com/token', scopes: { moviegoer: 'Can view Movies', }, }, }, }, OpenIdScheme: { type: 'openIdConnect', description: 'An openid-connect authorization scheme', openIdConnectUrl: 'https://myopenidserver.com/auth', }, }, responses: { ConsumedDrink: { description: 'Success, we consumed a drink!', content: { 'application/json': { schema: { $ref: '#/components/schemas/Drink', }, }, }, }, MovieWithETag: { description: 'Success, we retrieved a movie!', content: { 'application/json': { schema: { $ref: '#/components/schemas/Movie', }, }, }, headers: { ETag: { description: 'The unique version identifier of the movie.', schema: { $ref: '#/components/schemas/IdString', }, }, }, }, BarIsClosed: { description: 'Error, no drinks to be had!', content: { 'application/json': { schema: { $ref: '#/components/schemas/ErrorContainer', }, }, }, }, CarResponse: { description: 'The car instance was returned in the response.', content: { 'application/json': { schema: { $ref: '#/components/schemas/Car', }, examples: { ResponseExample: { $ref: '#/components/examples/CarExample', }, }, }, }, }, ErrorResponse: { description: 'An error occurred.', content: { 'application/json': { schema: { $ref: '#/components/schemas/ErrorContainer', }, }, }, }, }, requestBodies: { CarRequest: { required: true, content: { 'application/json': { schema: { $ref: '#/components/schemas/CarPrototype', }, examples: { RequestExample: { $ref: '#/components/examples/CarExample', }, }, }, }, }, UpdateCarRequest: { required: true, content: { 'application/merge-patch+json; charset=utf-8': { schema: { $ref: '#/components/schemas/CarPatch', }, examples: { RequestExample: { $ref: '#/components/examples/CarExample', }, }, }, }, }, }, examples: { CarExample: { description: 'An example of a Car instance.', value: { id: '1', make: 'Ford', model: 'F150 Lariat', }, }, }, links: { CarIdLink: { description: 'Link the `create_car` response `id` property to the `get_car` path parameter named `car_id`.', operationId: 'get_car', parameters: { car_id: '$response.body#/id', }, }, }, callbacks: {}, headers: {}, }, };