Allow oneOf to be an option rather than default

This commit is contained in:
Luke Hagar
2024-01-19 11:08:21 -06:00
parent cd5712a2a9
commit a2efe8289c
4 changed files with 54 additions and 21 deletions

View File

@@ -47,6 +47,11 @@ export type Config = {
* @description The type to use for null values * @description The type to use for null values
*/ */
nullType: 'number' | 'string' | 'integer' | 'boolean'; nullType: 'number' | 'string' | 'integer' | 'boolean';
/**
* @description Whether to allow oneOf for array items schema
*/
allowOneOf: boolean;
}; };
export type StringType = { export type StringType = {
@@ -125,10 +130,10 @@ export function convertArray(array: unknown[], config: Config) {
const output: ArrayType = { type: 'array' }; const output: ArrayType = { type: 'array' };
const items: Output[] = []; const items: Output[] = [];
const exampleArray = []; const exampleArray = [];
let schema = {};
for (const entry of array) { for (const entry of array) {
if (config.allowOneOf) {
const map = convertObject(entry, config); const map = convertObject(entry, config);
if ( if (
!items.some( !items.some(
(item) => (item) =>
@@ -141,13 +146,31 @@ export function convertArray(array: unknown[], config: Config) {
items.push(map); items.push(map);
exampleArray.push(entry); exampleArray.push(entry);
} }
} else {
items.push(entry);
if (typeof entry === 'object' && !Array.isArray(entry)) {
for (const prop in entry) {
schema[prop] = entry[prop];
}
}
}
} }
if (config.allowOneOf) {
if (items.length > 1) { if (items.length > 1) {
output.items = { oneOf: [...items] }; output.items = { oneOf: [...items] };
} else { } else {
output.items = items[0]; output.items = items[0];
} }
} else {
if (Object.keys(schema).length > 0) {
exampleArray.push(schema);
output.items = convertObject(schema, config);
} else {
exampleArray.push(items[0]);
output.items = convertObject(items[0], config);
}
}
if (config.includeExamples) output.example = exampleArray; if (config.includeExamples) output.example = exampleArray;

View File

@@ -5,7 +5,8 @@ import { localStorageStore } from '@skeletonlabs/skeleton';
const localConfig: Config = { const localConfig: Config = {
allowIntegers: true, allowIntegers: true,
includeExamples: true, includeExamples: true,
nullType: 'string' nullType: 'string',
allowOneOf: false
}; };
export const config: Writable<Config> = localStorageStore('config', localConfig); export const config: Writable<Config> = localStorageStore('config', localConfig);

View File

@@ -52,6 +52,15 @@
/> />
<p>Allow integer types</p> <p>Allow integer types</p>
</label> </label>
<label class="flex items-center space-x-2 text-sm">
<input
bind:checked={$config.allowOneOf}
class="checkbox"
type="checkbox"
id="allowOneOf"
/>
<p>Allow array oneOf</p>
</label>
</div> </div>
</div> </div>

View File

@@ -48,8 +48,8 @@
$: run(content, $config, $yamlOut); $: run(content, $config, $yamlOut);
</script> </script>
<div class="flex flex-row flex-wrap justify-between px-2 gap-2 overflow-hidden"> <div class="flex flex-row justify-between px-2 gap-2 overflow-hidden">
<div class="grow"> <div class="grow max-w-[50%]">
<p class="text-center py-2"> <p class="text-center py-2">
Input all of your JSON formatted Data, Typically API response bodies Input all of your JSON formatted Data, Typically API response bodies
</p> </p>
@@ -57,7 +57,7 @@
<JSONEditor onChange={() => run(content, $config, $yamlOut)} bind:content /> <JSONEditor onChange={() => run(content, $config, $yamlOut)} bind:content />
</div> </div>
</div> </div>
<div class="grow"> <div class="grow max-w-[50%]">
<p class="text-center py-2"> <p class="text-center py-2">
And here is that JSON Response formatted as a {$yamlOut === true ? 'YAML' : 'JSON'} OpenAPI Specification And here is that JSON Response formatted as a {$yamlOut === true ? 'YAML' : 'JSON'} OpenAPI Specification
</p> </p>