diff --git a/src/lib/converter.ts b/src/lib/converter.ts index e1cc999..005000a 100644 --- a/src/lib/converter.ts +++ b/src/lib/converter.ts @@ -47,6 +47,11 @@ export type Config = { * @description The type to use for null values */ nullType: 'number' | 'string' | 'integer' | 'boolean'; + + /** + * @description Whether to allow oneOf for array items schema + */ + allowOneOf: boolean; }; export type StringType = { @@ -125,28 +130,46 @@ export function convertArray(array: unknown[], config: Config) { const output: ArrayType = { type: 'array' }; const items: Output[] = []; const exampleArray = []; - + let schema = {}; for (const entry of array) { - const map = convertObject(entry, config); - - if ( - !items.some( - (item) => - (item.type === map.type && item.format === map.format && item.type !== 'object') || - (item.type === 'object' && - JSON.stringify(Object.keys(item.properties).sort()) === - JSON.stringify(Object.keys(map.properties).sort())) - ) - ) { - items.push(map); - exampleArray.push(entry); + if (config.allowOneOf) { + const map = convertObject(entry, config); + if ( + !items.some( + (item) => + (item.type === map.type && item.format === map.format && item.type !== 'object') || + (item.type === 'object' && + JSON.stringify(Object.keys(item.properties).sort()) === + JSON.stringify(Object.keys(map.properties).sort())) + ) + ) { + items.push(map); + exampleArray.push(entry); + } + } else { + items.push(entry); + if (typeof entry === 'object' && !Array.isArray(entry)) { + for (const prop in entry) { + schema[prop] = entry[prop]; + } + } } } - if (items.length > 1) { - output.items = { oneOf: [...items] }; + if (config.allowOneOf) { + if (items.length > 1) { + output.items = { oneOf: [...items] }; + } else { + output.items = items[0]; + } } else { - output.items = items[0]; + 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; diff --git a/src/lib/store.ts b/src/lib/store.ts index 359ca0f..ecd4e37 100644 --- a/src/lib/store.ts +++ b/src/lib/store.ts @@ -5,7 +5,8 @@ import { localStorageStore } from '@skeletonlabs/skeleton'; const localConfig: Config = { allowIntegers: true, includeExamples: true, - nullType: 'string' + nullType: 'string', + allowOneOf: false }; export const config: Writable = localStorageStore('config', localConfig); diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte index 2cb99dc..357596d 100644 --- a/src/routes/+layout.svelte +++ b/src/routes/+layout.svelte @@ -52,6 +52,15 @@ />

Allow integer types

+ diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte index ad12338..4e86ecb 100644 --- a/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -48,8 +48,8 @@ $: run(content, $config, $yamlOut); -
-
+
+

Input all of your JSON formatted Data, Typically API response bodies

@@ -57,7 +57,7 @@ run(content, $config, $yamlOut)} bind:content />
-
+

And here is that JSON Response formatted as a {$yamlOut === true ? 'YAML' : 'JSON'} OpenAPI Specification