redocly / openapi-sampler Goto Github PK
View Code? Open in Web Editor NEW:capital_abcd: Tool for generation samples based on OpenAPI(fka Swagger) payload/response schema
License: MIT License
:capital_abcd: Tool for generation samples based on OpenAPI(fka Swagger) payload/response schema
License: MIT License
readOnly
& writeOnly
are not honored when they are set in an allOf block to edit an objects properties.
E.g. we got these components:
openapi: 3.0.0
info:
title: Test
version: 0.1.0
paths:
/users:
get:
summary: Get Users
operationId: getAllAccounts
responses:
200:
description: Default
content:
application/json:
schema:
$ref: '#/components/schemas/User'
post:
summary: Create User
operationId: createUser
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/User'
responses:
201:
description: 'User created'
/users/{userId}:
patch:
summary: Update User
operationId: updateUser
parameters:
- in: path
name: userId
schema:
type: string
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/PatchUser'
responses:
200:
description: 'User updated'
components:
schemas:
User:
type: object
properties:
id:
type: integer
readOnly: true
tenant_id:
type: integer
username:
type: string
PatchUser:
allOf:
- $ref: '#/components/schemas/User'
- type: object
properties:
tenant_id:
readOnly: true
Assuming the id
of a User
will never change and User
is used to create and read the user and PatchUser
is used to update it.
This setup would disallow to patch the tenant_id
of a user, but keeps it writable when the user is created. Exactly that is not shown correctly in the request samples tab. It keeps showing the tenant_id
in the request sample which implies it is updatable when it is not. The request body schema omits the tenant_id
correctly.
Hello! I have schema like here:
arrayValueRank:
description: >
This Attribute indicates whether the val Attribute of the datapoint is an
array and how many dimensions the array has.
type: integer
default: -1
examples:
- 2
oneOf:
- const: -1
description: 'Scalar: The value is not an array.'
- const: 0
description: 'OneOrMoreDimensions: The value is an array with one or more dimensions.'
- const: 1
description: 'OneDimension: The value is an array with one dimension.'
- const: 2
description: 'The value is an array with two dimensions.'
arrayArrayDimensions:
type: array
items:
type: integer
minimum: 0
examples:
- [3, 5]
and then the example should look like:
"valueRank": 2,
"arrayDimensions": [
3,
5
],
but package produces:
"valueRank": -1,
"arrayDimensions": [
3,
5
],
So I see two bugs there:
const
should take precedence over other keywords. At the moment package infer examples in order: default
-> const
-> enum
-> examples[0]
-> generate example using format, but I think that const
should take precedence over other keywords.examples
, default
, const
with oneOf
like in schema above, package should infer examples from root schema, not from first oneOf
item -> problem with this line. This problem should be also handled for other combined keywords like allOf
.The package is very helpful in our project and fixing this problem itself should not be difficult :) Thanks!
Schema
{
type: "array",
"x-nullable": false,
items: {
type: "array",
items: {
type: "string",
minLength: 1,
},
},
description: "nested arrays"
}
Validation
validator.validateModel(
[
['1'],['2']
],
schema,
Error
TypeError: Cannot set property 'arrayPos' of undefined
at /Users/node_modules/swagger-object-validator/lib/validators/ArrayValidator.js:40:48
at Array.forEach (<anonymous>)
at validateArray (/Users/node_modules/swagger-object-validator/lib/validators/ArrayValidator.js:38:10)
at /Users//node_modules/swagger-object-validator/lib/validators/ModelValidator.js:58:29
From previous event:
at Object.validateModel (/Users/node_modules/swagger-object-validator/lib/validators/ModelValidator.js:26:10)
at /Users/node_modules/swagger-object-validator/lib/handler.js:46:67
From previous event:
at /Users/node_modules/swagger-object-validator/lib/handler.js:46:18
Hi, thanks for providing such a library for the community. We are using redoc in our code and we found a potential issue in the generated JSON and we traced it down to this library. I compared the OpenAPI doc we generate using the https://editor.swagger.io/ to see if we were diverging from what is expected and apparently it is a bug here in openapi-sampler.
It happens when we use the OneOf and it generates the wrong output. To best exemplify, I created a test for the object.spec.js file.
Please let me know what you think.
it('should generate both items of oneOf', () => {
res = sampleObject({
'type': 'object',
'properties': {
'my_obj': {
'type': 'object',
'properties': {
'elements': {
'items': {
'oneOf': [
{
'type': 'object',
'properties': {
'name': {
'type': 'string',
'description': '',
'enum': [
'obj_a'
]
}
},
'title': 'obj_a',
'required': [
'name'
]
},
{
'type': 'object',
'properties': {
'name': {
'type': 'string',
'description': '',
'enum': [
'obj_b'
]
}
},
'title': 'obj_b',
'required': [
'name'
]
}
]
},
'type': 'array',
'minItems': 2,
'maxItems': 2,
'uniqueItems': true
}
},
'title': '',
'required': [
'elements'
]
}
},
'required': [
'my_obj'
]
})
expect(res).deep.equal({
'my_obj': {
'elements': [
{
'name': 'obj_a'
},
{
'name': 'obj_b'
}
]
}
})
});
Apparently OpenAPI sampler is ignoring the format
keyword for numbers/integers โ which leads to incorrect examples when they are specified.
Given this schema:
sampleObject(
{
properties: {
a: { type: 'string' },
b: {
type: 'object',
oneOf: [
{
type: 'object',
properties: {
c: {
type: 'string',
},
},
},
{
type: 'object',
properties: {
d: {
type: 'string',
},
},
},
],
readOnly: true,
},
},
},
{ skipReadOnly: true }
)
the readOnly property on the top-level object is being ignored, and the property b
will be returned in the schema. It should not, since it is readonly.
Also npm i
reports
found 15 vulnerabilities (6 low, 5 moderate, 4 high)
I'm attempting to use Redoc however openapi sampler is unable to recognize the object spread operator. Babel is set up in my project and works elsewhere. Stack trace:
.//openapi-sampler/src/openapi-sampler.js 1:0-50/redoc/bundles/redoc.browser.lib.js
./
Got a crash in allOf.js
import { traverse } from './traverse';
import { mergeDeep } from './utils';
export function allOfSample(into, children, options, spec) {
let res = traverse(into, options, spec);
const subSamples = [];
for (let subSchema of children) {
const { type, readOnly, writeOnly, value } = traverse({ type, ...subSchema }, options, spec);
if (res.type && type && type !== res.type) {
throw new Error('allOf: schemas with different types can\'t be merged');
}
which yeild: ReferenceError: Cannot access 'type' before initialization (at the second traverse call)
SubSchema is:
[$ref: "#/components/schemas/cursor"]
Where does type come from in the second traverse function? There is something I'm missing since that code passed you're test before.
This is a feature request.
Would it be possible to change the default example value for the integer type?
Right now the default is 0
, but since an integer is usually an id, it often makes more sense to use 1
in the examples.
Right now, the workaround is to specify the example every time an integer type is defined.
Not sure if this feature request would make sense for other types as well?
Version 1.0.0-beta1
I believe related to the new resolution of $ref
s and circular references. I wasn't able to produce an artificial test-case which generated the error though.
Test-case (requires patientview API file from openapi-directory):
let util = require('util');
let fs = require('fs');
let sampler = require('openapi-sampler');
let yaml = require('js-yaml');
let apiStr = fs.readFileSync('../openapi-directory/APIs/patientview.org/1.0/swagger.yaml','utf8');
let api = yaml.safeLoad(apiStr,{json:true});
let schema = api.definitions.Group;
let sample = sampler.sample(schema,{},api);
console.log(util.inspect(sample));
At this moment when someone is using additionalProperties
it generates property1
and property2
as key names. Sampler could use the x-additionalPropertiesName
property to generate custom property names:
{
additionalProperties: {
type: 'string',
'x-additionalPropertiesName': 'attribute-name'
}
}
Generates:
{
'property1': 'string',
'property2': 'string'
}
and the output should look like this:
{
'attribute-name1': 'string',
'attribute-name2': 'string'
}
Default property name should remain the same when no x-additionalPropertiesName
is defined.
This is not a standard property of additionalProperties
but Redocly supports it in the schema definition. I'll make a PR to change it.
Our other projects use Jest for testing, so it's not seamless to move back and forth. Should we migrate the tests to Jest?
startDate in following example code returned as 2019-04-24 instead of today's date in version 1.0.0-beta.16. code works fine in version version 1.0.0-beta.15.
const sampler = require("openapi-sampler");
console.log(sampler.sample({"type":"array",
"items":{"type":"object",
"required":["id","name"],
"properties":
{"name":{"type":"string"},
"tag":{"type":"string"},
"startDate":{"type":"string","format":"date"}}},
"$schema":"http://json-schema.org/draft-04/schema#"}, {skipReadOnly: true}));
When the content type is xml the xml properties should be used to generate an xml output, not a json one.
We are receiving error below, when trying to generate documentation via redoc-cli
tool.
redoc-cli
calls openapi-sampler
and does not work properly with keys in swagger.
``` components: schemas: Required__%5BkeyinDeliverableWithWriterAlias%5D%3Aboolean--__: properties: system-administration: type: boolean system-use: type: boolean required: - system-administration - system-use type: object description: 'Make all properties in T required' ReleaseNotificationsBody: properties: commentsAll: type: boolean comments: $ref: '#/components/schemas/Required__%5BkeyinDeliverableWithWriterAlias%5D%3Aboolean--__' required: - commentsAll - comments type: object additionalProperties: false info: title: 'API v1' version: 3.18.0 openapi: 3.0.0 paths: '/releases/{releaseVersionId}/notifications': put: operationId: updateNotifications responses: '200': description: 'Release notifications updated' content: application/json: schema: $ref: '#/components/schemas/ReleaseNotificationsBody' summary: 'Update Release Notifications for current user' parameters: - in: path name: releaseVersionId required: true schema: $ref: '#/components/schemas/ReleaseVersionId' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/ReleaseNotificationsBody' get: operationId: getNotifications responses: '200': description: 'Get release notifications' content: application/json: schema: $ref: '#/components/schemas/ReleaseNotificationsBody' summary: 'Get Release Notifications for current user' parameters: - in: path name: releaseVersionId required: true schema: $ref: '#/components/schemas/ReleaseVersionId' ```
Error: Invalid reference token: Required__[keyinDeliverableWithWriterAlias]:boolean--__
at Function.get (/sr/app/node modules/openapi-sampler/dist/openapi-sampler.js:79:19)
at traverse (/usr/app/node_modules/openapi-sampler/dist/openapi-sampler.js:947:43)
at /usr/app/node_modules/openapi-sampler/dist/openapi-sampler.is:646:43
at Arrav.forEach(<anonvmous>)
at sample0biect (/us/app/node modules/openapi-sampler/dist/openapi-sampler.is:640:36
at traverse (/usr/app/node_modules/openapi-sampler/dist/openapi-sampler.js:1033:17)
at traverse (/usr/app/node_modules/openapi-sampler/dist/openapi-sampler.is:953:16)
at Object.sample (/usr/app/node_modules/openapi-sampler/dist/openapi-sampler.js:426:33)
at Hn.generateExample (/usr/app/node modules/redoc/bundles/redoc.lib.is:41:73780)
at new Hn (/usr/app/node modules/redoc/bundles/redoc. lib.js:41:73198)
What helped us is this patch:
diff --git a/node_modules/openapi-sampler/dist/openapi-sampler.js b/node_modules/openapi-sampler/dist/openapi-sampler.js
index 55fc164..4431786 100644
--- a/node_modules/openapi-sampler/dist/openapi-sampler.js
+++ b/node_modules/openapi-sampler/dist/openapi-sampler.js
@@ -938,7 +938,7 @@ function traverse(schema, options, spec, context) {
throw new Error('Your schema contains $ref. You must provide full specification in the third parameter.');
}
- var ref = decodeURIComponent(schema.$ref);
+ var ref = schema.$ref; // Fixes: "Error: Invalid reference token: Required__[keyinDeliverableWithWriterAlias]:boolean--__"
if (ref.startsWith('#')) {
ref = ref.substring(1);
Generated examples are not valid when using regular expression patterns.
In this case, the example is simply "string" without honoring the regular expression.
Steps to replicate:
openapi: 3.0.3
info:
version: 1.0.0
title: Test
description: Test
servers:
- url: "/api/1"
paths:
/test:
get:
operationId: Test
summary: Test
description: Test
responses:
"200":
description: Test
content:
application/json:
schema:
type: object
properties:
test:
type: string
pattern: "^[0-9]{5,8}$"
Observe the example rendered as {"test": "string"}
that is not valid against the schema.
Original issue: Redocly/redoc#2312
See reproduced example here:
https://codesandbox.io/p/sandbox/openapi-sampler-oneof-bug-ignfcs
I have the following schema:
{
type: "object",
properties: {
a: {
type: "string",
},
b: {
type: "string",
},
},
oneOf: [
{
required: ["a"],
},
{
required: ["b"],
},
],
};
Since either a
is required or b
is required I would expect {a: "string"}
or {b: "string"}
to be correct examples for this schema.
openapi-sampler
produces {a: "string", b: "string"}
as an example which is incorrect. The error given by asyncapi parser is must match exactly one schema in oneOf
.
If I add the {skipNonRequired: true}
option then the example becomes {}
which is also incorrect.
On input such as
{
"description": "Authentiq ID in JWT format, self-signed.\n",
"properties": {
"devtoken": {
"description": "device token for push messages",
"type": "string"
},
"sub": {
"description": "UUID and public signing key",
"type": "string"
}
},
"required": [
"sub"
]
}
Which 0.3.3 samples correctly.
Are we sure about c13e51b? type
isn't a mandatory keyword and at least enum
can be used without it.
Type inference seems to be a common approach.
This is a feature request.
Would be great if lib supports generation example for time
format, like in spec:
{
"type": "string",
"format": "time"
}
and then output should be:
14:15:22
At the moment lib supports generation for date
and date-time
, but time
should be also supported. As I know format
is a open value, so it shouldn't be against the OpenAPI specification link, but maybe there are issues as to why time
format is not documented.
We have a reported issue in our library (which uses openapi-sampler
) to supports time
format and we don't want to make example inside library, but want to have support in used package.
I can make PR for it if you'll accept my request :)
Btw. Very helpful library :)
Minimal schema example (example includes both properties instead of max both equal to 1).
type: object
minProperties: 1
maxProperties: 1
properties:
quantity:
type: integer
description: Usage limit quantity.
minimum: 1
amount:
type: number
format: double
description: Usage limit amount in the currency of the order.
minimum: 0.01
In this case since there is a maxProperties value of one I would expect it to return the first property in the sample.
This misses a file about how to contribute, add tests, run tests, link to our code of conduct, etc.
Hi. I noticed that you have support for circular refs detection in case I have $ref
that is circular
openapi-sampler/test/integration.spec.js
Line 507 in a5ded39
The thing is that your not follow
approach is used only in case of $ref
https://github.com/Redocly/openapi-sampler/blob/master/src/traverse.js#L26-L37.
I have a use case where my schema is fully dereferenced, still circular though, and now I obviously get Maximum call stack size exceeded
error. Have you considered support for such use cases?
Do you support or have plans to support generating XML samples?
Can you give some examples of what the spec
value would be?
thanks
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.