Skip to content

Commit 3f64fd0

Browse files
committed
Generate pre req variables example values when parsing openapi spec
1 parent d7bc0c8 commit 3f64fd0

4 files changed

Lines changed: 359 additions & 127 deletions

File tree

Lines changed: 38 additions & 123 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
const { generateRequestBodyExample } = require('./generate-request-body');
2+
const {
3+
generateQueryParamsExample,
4+
generateParameterExample,
5+
generatePathParamsExample,
6+
} = require('./generate-request-parameters');
7+
18
const computeUrl = (baseUrl, path) => {
29
if (baseUrl.charAt(baseUrl.length - 1) === '/' && path.charAt(0) === '/') {
310
return baseUrl + path.substring(1, path.length);
@@ -16,127 +23,6 @@ const replaceSingleToDoubleCurlyBraces = (str) => {
1623
return str;
1724
};
1825

19-
const generateExample = (schema) => {
20-
if (!schema) return {};
21-
22-
if (schema.enum) {
23-
return schema.example || schema.enum[0];
24-
}
25-
26-
if (schema.oneOf) {
27-
return generateExample(schema.oneOf[0]);
28-
}
29-
30-
if (schema.anyOf) {
31-
return generateExample(schema.anyOf[0]);
32-
}
33-
34-
if (schema.allOf) {
35-
return generateAllOfExample(schema.allOf);
36-
}
37-
38-
switch (schema.type) {
39-
case 'object':
40-
return generateObjectExample(schema);
41-
case 'array':
42-
return generateArrayExample(schema);
43-
case 'string':
44-
return generateStringExample(schema);
45-
case 'integer':
46-
return generateIntegerExample(schema);
47-
case 'number':
48-
return generateNumberExample(schema);
49-
case 'boolean':
50-
return schema.example || true;
51-
default:
52-
return schema.example || null;
53-
}
54-
};
55-
56-
const generateAllOfExample = (schemas) => {
57-
const example = {};
58-
schemas.forEach((subSchema) => {
59-
const subExample = generateExample(subSchema);
60-
Object.assign(example, subExample);
61-
});
62-
return example;
63-
};
64-
65-
const generateObjectExample = (schema) => {
66-
const example = {};
67-
const properties = schema.properties || {};
68-
69-
for (const [key, propertySchema] of Object.entries(properties)) {
70-
example[key] = generateExample(propertySchema);
71-
}
72-
73-
return example;
74-
};
75-
76-
const generateArrayExample = (schema) => {
77-
const itemsSchema = schema.items || {};
78-
return [generateExample(itemsSchema)];
79-
};
80-
81-
const generateStringExample = (schema) => {
82-
let example = schema.example || 'string';
83-
84-
if (schema.minLength || schema.maxLength) {
85-
example = generateStringWithLengthConstraints(example, schema.minLength, schema.maxLength);
86-
}
87-
88-
switch (schema.format) {
89-
case 'date-time':
90-
return schema.example || new Date().toISOString();
91-
case 'date':
92-
return schema.example || new Date().toISOString().split('T')[0];
93-
case 'email':
94-
return schema.example || 'example@example.com';
95-
case 'uuid':
96-
return schema.example || '123e4567-e89b-12d3-a456-426614174000';
97-
case 'uri':
98-
return schema.example || 'https://example.com';
99-
case 'hostname':
100-
return schema.example || 'example.com';
101-
case 'ipv4':
102-
return schema.example || '192.168.0.1';
103-
case 'ipv6':
104-
return schema.example || '2001:0db8:85a3:0000:0000:8a2e:0370:7334';
105-
case 'byte':
106-
return schema.example || btoa('example');
107-
case 'binary':
108-
return schema.example || 'binary data';
109-
case 'password':
110-
return schema.example || 'password';
111-
default:
112-
return example;
113-
}
114-
};
115-
116-
const generateStringWithLengthConstraints = (str, minLength, maxLength) => {
117-
if (minLength) {
118-
while (str.length < minLength) {
119-
str += 'a';
120-
}
121-
}
122-
if (maxLength) {
123-
str = str.substring(0, maxLength);
124-
}
125-
return str;
126-
};
127-
128-
const generateIntegerExample = (schema) => {
129-
const min = schema.minimum || 0;
130-
const max = schema.maximum || min + 100;
131-
return schema.example || Math.floor(Math.random() * (max - min + 1)) + min;
132-
};
133-
134-
const generateNumberExample = (schema) => {
135-
const min = schema.minimum || 0.0;
136-
const max = schema.maximum || min + 100.0;
137-
return schema.example || Math.random() * (max - min) + min;
138-
};
139-
14026
const parseOpenAPISpec = (collection) => {
14127
let parsedNodes = [];
14228
try {
@@ -150,6 +36,8 @@ const parseOpenAPISpec = (collection) => {
15036
var url = replaceSingleToDoubleCurlyBraces(computeUrl(baseUrl, path));
15137
var variables = {};
15238
var requestBody = {};
39+
const pathParameters = [];
40+
const queryParameters = [];
15341

15442
if (request['parameters']) {
15543
let firstQueryParam = true;
@@ -164,15 +52,42 @@ const parseOpenAPISpec = (collection) => {
16452
} else {
16553
url = url.concat(`&${value['name']}={{${value['name']}}}`);
16654
}
55+
queryParameters.push(value);
56+
}
57+
58+
if (value['in'] === 'path') {
59+
pathParameters.push(value);
16760
}
16861
});
16962
}
17063

64+
if (queryParameters.length > 0) {
65+
const res = generateQueryParamsExample(queryParameters);
66+
Array.from(res.entries()).map(([key, value], index) => {
67+
variables[key] = {
68+
type: typeof value,
69+
value,
70+
};
71+
});
72+
}
73+
74+
if (pathParameters.length > 0) {
75+
const res = generatePathParamsExample(pathParameters);
76+
Array.from(res.entries()).map(([key, value], index) => {
77+
variables[key] = {
78+
type: typeof value,
79+
value,
80+
};
81+
});
82+
}
83+
17184
if (request['requestBody']) {
17285
if (request['requestBody']['content']['application/json']) {
17386
requestBody = {
17487
type: 'raw-json',
175-
body: JSON.stringify(generateExample(request['requestBody']['content']['application/json']['schema'])),
88+
body: JSON.stringify(
89+
generateRequestBodyExample(request['requestBody']['content']['application/json']['schema']),
90+
),
17691
};
17792
}
17893

@@ -195,6 +110,7 @@ const parseOpenAPISpec = (collection) => {
195110
requestType: requestType.toUpperCase(),
196111
tags: tags,
197112
requestBody,
113+
preReqVars: variables,
198114
};
199115

200116
parsedNodes.push(finalNode);
@@ -208,5 +124,4 @@ const parseOpenAPISpec = (collection) => {
208124

209125
module.exports = {
210126
parseOpenAPISpec,
211-
generateExample,
212127
};

packages/flowtest-electron/src/utils/collection.test.js

Lines changed: 87 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,16 @@
1-
const { generateExample } = require('./collection.js');
1+
const { generateRequestBodyExample } = require('./generate-request-body.js');
2+
const { generatePathParamsExample, generateQueryParamsExample } = require('./generate-request-parameters.js');
23

34
describe('collection parser', () => {
45
it('should generate request body example', () => {
5-
console.log(JSON.stringify(generateExample(userSchema), null, 2));
6-
console.log(JSON.stringify(generateExample(productSchema), null, 2));
7-
console.log(JSON.stringify(generateExample(complexSchema), null, 2));
6+
console.log(JSON.stringify(generateRequestBodyExample(userSchema), null, 2));
7+
console.log(JSON.stringify(generateRequestBodyExample(productSchema), null, 2));
8+
console.log(JSON.stringify(generateRequestBodyExample(complexSchema), null, 2));
9+
});
10+
11+
it('should generate request parameters example', () => {
12+
console.log('Path Parameters Example:', generatePathParamsExample(pathParameters).toString());
13+
console.log('Query Parameters Example:', generateQueryParamsExample(queryParameters).toString());
814
});
915
});
1016

@@ -136,3 +142,80 @@ const complexSchema = {
136142
},
137143
},
138144
};
145+
146+
// Example usage:
147+
148+
const pathParameters = [
149+
{
150+
name: 'userId',
151+
in: 'path',
152+
required: true,
153+
schema: {
154+
type: 'integer',
155+
format: 'int64',
156+
example: 123,
157+
minimum: 1,
158+
},
159+
},
160+
{
161+
name: 'username',
162+
in: 'path',
163+
required: true,
164+
schema: {
165+
type: 'string',
166+
minLength: 3,
167+
maxLength: 20,
168+
example: 'john_doe',
169+
},
170+
},
171+
];
172+
173+
const queryParameters = [
174+
{
175+
name: 'page',
176+
in: 'query',
177+
schema: {
178+
type: 'integer',
179+
example: 1,
180+
minimum: 1,
181+
},
182+
},
183+
{
184+
name: 'limit',
185+
in: 'query',
186+
schema: {
187+
type: 'integer',
188+
example: 10,
189+
minimum: 1,
190+
maximum: 100,
191+
},
192+
},
193+
{
194+
name: 'sort',
195+
in: 'query',
196+
schema: {
197+
type: 'string',
198+
enum: ['asc', 'desc'],
199+
example: 'asc',
200+
},
201+
},
202+
{
203+
name: 'filter',
204+
in: 'query',
205+
schema: {
206+
type: 'array',
207+
items: {
208+
type: 'string',
209+
example: 'status:active',
210+
},
211+
},
212+
},
213+
{
214+
name: 'search',
215+
in: 'query',
216+
schema: {
217+
type: 'string',
218+
example: 'example',
219+
},
220+
},
221+
];

0 commit comments

Comments
 (0)