Skip to content

Commit

Permalink
Merge pull request #31 from barnuri/fix-any-of
Browse files Browse the repository at this point in the history
fix-any-of
  • Loading branch information
barnuri authored Jul 3, 2024
2 parents 551fe15 + 3ab16a5 commit 0a7c4b1
Show file tree
Hide file tree
Showing 8 changed files with 106,582 additions and 32 deletions.
106,523 changes: 106,523 additions & 0 deletions .github/complexSwagger.json

Large diffs are not rendered by default.

4 changes: 3 additions & 1 deletion .github/workflows/runTests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ on:
pull_request:
branches: [ master ]
env:
OPENAPI_TOOLKIT_TESTFILE: "${{ github.workspace }}/swagger.json"
OPENAPI_TOOLKIT_TESTFILE: "${{ github.workspace }}/.github/complexSwagger.json"
jobs:
prepare:
runs-on: ubuntu-latest
Expand Down Expand Up @@ -113,6 +113,7 @@ jobs:
path: ./*
key: ${{ github.sha }}
- run: npm run test:go
continue-on-error: true

test-go-server:
name: Test Go Server
Expand All @@ -125,3 +126,4 @@ jobs:
path: ./*
key: ${{ github.sha }}
- run: npm run test:go-server
continue-on-error: true
43 changes: 22 additions & 21 deletions src/helpers/getEditor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,57 +16,58 @@ import { cloneHelper, distinct } from './utilsHelper';

type existingObjectEditorInputs = { [inputName: string]: EditorObjectInput };

export function getEditor(openApiDocument: OpenApiDocument, editorName: string, includeInheritProps: boolean = false): Editor {
export function getEditor(openApiDocument: OpenApiDocument, editorName: string, includeInheritProps: boolean = true): Editor {
let definitions = getDefinisions(openApiDocument);
const existingObjectEditorInputs: existingObjectEditorInputs = {};
const editor = new Editor();
editor.name = editorName;
editor.editorAsInput = getEditorInput2(openApiDocument, definitions[editorName]);
const editorProps = getOpenApiDefinitionObjectProps(definitions[editorName], includeInheritProps, definitions);
const editorProps = getOpenApiDefinitionObjectProps(openApiDocument, definitions[editorName], includeInheritProps, definitions);
editor.inputs = Object.keys(editorProps).map(inputName =>
getEditorInput(definitions, inputName, editorProps[inputName], definitions[editorName], inputName, existingObjectEditorInputs),
getEditorInput(openApiDocument, definitions, inputName, editorProps[inputName], definitions[editorName], inputName, existingObjectEditorInputs),
);
editor.editorAsInput.className = editorName;
return editor;
}

export function getEditorInput2(openApiDocument: OpenApiDocument, definition: OpenApiDefinition): EditorInput {
return getEditorInput(getDefinisions(openApiDocument || {}), '', definition || {}, undefined, undefined, {});
return getEditorInput(openApiDocument, getDefinisions(openApiDocument || {}), '', definition || {}, undefined, undefined, {});
}

export function getEditorInput(
openApiDocument: OpenApiDocument,
definitions: OpenApiDefinitionsDictionary,
path: string,
definition: OpenApiDefinition,
parentDefinition: OpenApiDefinitionObject | undefined,
customRefName?: string,
existingObjectEditorInputs: existingObjectEditorInputs = {},
): EditorInput {
const defDetails = getOpenApiDefinitionObject(definition, definitions);
let definitionObj = defDetails.def || {};
const defDetails = getOpenApiDefinitionObject(openApiDocument, definition, definitions);
let definitionObj = defDetails.def;
definitionObj.anyOf = definitionObj.anyOf ? definitionObj.anyOf.filter(x => x.title != definitionObj.title) : definitionObj.anyOf;
defDetails.refName = defDetails.refName || customRefName || '';
if (Array.isArray(definitionObj.type)) {
definitionObj.type = [...definitionObj.type, 'string'].filter(x => x != 'null')[0] as OpenApiDefinitionType;
}
if (isPrimitive(definitionObj)) {
const primitive = new EditorPrimitiveInput(getPrimitiveType(definitionObj)!, path, definitionObj, parentDefinition, definitions);
const primitive = new EditorPrimitiveInput(openApiDocument, getPrimitiveType(definitionObj)!, path, definitionObj, parentDefinition, definitions);
primitive.className = defDetails.refName;
return primitive;
}
if (definitionObj.type == 'array') {
path = path + '[i]';
const itemOpenApiObj = getOpenApiDefinitionObject(definitionObj.items!, definitions);
const itemOpenApiObj = getOpenApiDefinitionObject(openApiDocument, definitionObj.items!, definitions);
if (path == '.configurations[i]') {
const a = 1;
}
const itemInput = getEditorInput(definitions, path, itemOpenApiObj.def, parentDefinition, itemOpenApiObj.refName, existingObjectEditorInputs);
const itemInput = getEditorInput(openApiDocument, definitions, path, itemOpenApiObj.def, parentDefinition, itemOpenApiObj.refName, existingObjectEditorInputs);
itemInput.className = itemOpenApiObj.refName;
return new EditorArrayInput(itemInput, path, definitionObj, parentDefinition, definitions);
return new EditorArrayInput(openApiDocument, itemInput, path, definitionObj, parentDefinition, definitions);
}

definitionObj.anyOf = definitionObj.anyOf || [];
const objectInput = new EditorObjectInput([], path, defDetails.refName, definitionObj, parentDefinition, definitions);
const objectInput = new EditorObjectInput(openApiDocument, [], path, defDetails.refName, definitionObj, parentDefinition, definitions);
objectInput.className = defDetails.refName || customRefName;
if (objectInput.definistionName) {
const key = `${objectInput.definistionName}-${objectInput.required}-${defDetails.ignoreInherit}`;
Expand All @@ -76,12 +77,12 @@ export function getEditorInput(
}
existingObjectEditorInputs[key] = objectInput;
}
const props = getOpenApiDefinitionObjectProps(definitionObj, !defDetails.ignoreInherit, definitions);
const props = getOpenApiDefinitionObjectProps(openApiDocument, definitionObj, !defDetails.ignoreInherit, definitions);
const propsInputs: EditorInput[] = [];
for (const propContainerName of Object.keys(props)) {
const details = getOpenApiDefinitionObject(props[propContainerName], definitions);
const details = getOpenApiDefinitionObject(openApiDocument, props[propContainerName], definitions);
propsInputs.push(
getEditorInput(definitions, `${path}.${propContainerName}`, props[propContainerName], definitionObj, details.refName, existingObjectEditorInputs),
getEditorInput(openApiDocument, definitions, `${path}.${propContainerName}`, props[propContainerName], definitionObj, details.refName, existingObjectEditorInputs),
);
}
const switchableObjects: EditorInput[] = [];
Expand All @@ -90,7 +91,7 @@ export function getEditorInput(
continue;
}
definitions = { ...getDefinisions(switchable), ...definitions };
const switchableObject = cloneHelper(getEditorInput(definitions, path, switchable, parentDefinition, switchable.title, existingObjectEditorInputs));
const switchableObject = cloneHelper(getEditorInput(openApiDocument, definitions, path, switchable, parentDefinition, switchable.title, existingObjectEditorInputs));
if (switchableObject.editorType === 'EditorObjectInput') {
(switchableObject as EditorObjectInput).properties = (switchableObject as EditorObjectInput).properties.filter(
x => !propsInputs.map(x => x.name).includes(x.name),
Expand All @@ -106,22 +107,22 @@ export function getEditorInput(
let dictionaryInput: EditorInput | undefined = undefined;
let dictionaryKeyInput: EditorInput | undefined = undefined;
if (objectInput.isDictionary) {
dictionaryInput = new EditorPrimitiveInput('string', path, definitionObj, parentDefinition, definitions);
dictionaryInput = new EditorPrimitiveInput(openApiDocument, 'string', path, definitionObj, parentDefinition, definitions);
if (!!definitionObj.additionalProperties) {
try {
const dictOpenApiObj = getOpenApiDefinitionObject(definitionObj.additionalProperties as any, definitions);
dictionaryInput = getEditorInput(definitions, path, dictOpenApiObj.def, definitionObj, undefined, existingObjectEditorInputs);
const dictOpenApiObj = getOpenApiDefinitionObject(openApiDocument, definitionObj.additionalProperties as any, definitions);
dictionaryInput = getEditorInput(openApiDocument, definitions, path, dictOpenApiObj.def, definitionObj, undefined, existingObjectEditorInputs);
dictionaryInput.className = dictOpenApiObj.refName;
} catch {}
}
dictionaryInput.name = 'value';

const dictionaryKeyInputObj = definitionObj['x-dictionaryKey'];
dictionaryKeyInput = new EditorPrimitiveInput('string', path, definitionObj, parentDefinition, definitions);
dictionaryKeyInput = new EditorPrimitiveInput(openApiDocument, 'string', path, definitionObj, parentDefinition, definitions);
if (!!dictionaryKeyInputObj) {
try {
const dictOpenApiObj = getOpenApiDefinitionObject(dictionaryKeyInputObj as any, definitions);
dictionaryKeyInput = getEditorInput(definitions, path, dictOpenApiObj.def, definitionObj, undefined, existingObjectEditorInputs);
const dictOpenApiObj = getOpenApiDefinitionObject(openApiDocument, dictionaryKeyInputObj as any, definitions);
dictionaryKeyInput = getEditorInput(openApiDocument, definitions, path, dictOpenApiObj.def, definitionObj, undefined, existingObjectEditorInputs);
dictionaryKeyInput.className = dictOpenApiObj.refName;
} catch {}
}
Expand Down
26 changes: 20 additions & 6 deletions src/helpers/openApiHelper.ts
Original file line number Diff line number Diff line change
@@ -1,31 +1,44 @@
import { OpenApiPathParamInVals } from './../models/openapi/OpenApiDocument';
import { OpenApiDefinition, OpenApiDocument, OpenApiDefinitionReference, OpenApiDefinitionObject, OpenApiDefinitionsDictionary, ApiPath } from '../models';
import { cleanString } from '../helpers/utilsHelper';
import { cleanString, jsonPath } from '../helpers/utilsHelper';

export function getOpenApiDefinitionObject(
openApiDocument: OpenApiDocument,
definition: OpenApiDefinition,
definitions: OpenApiDefinitionsDictionary,
): { def: OpenApiDefinitionObject; refName: string | undefined; ignoreInherit: boolean } {
definition = definition || {};
definitions = definitions || {};
const ignoreInherit = definition['x-ignore-inherit'] === true;
if (Object.keys(definition).includes('$ref')) {
const refName = (definition as OpenApiDefinitionReference).$ref.split('/').splice(-1)[0];
return { def: definitions[refName], refName, ignoreInherit };
const refPath = (definition as OpenApiDefinitionReference).$ref;
if (refPath.includes('/anyOf/') || refPath.includes('/oneOf/') || refPath.includes('/allOf/')) {
const refJsonPath = refPath.replace(/#/g, '').replace(/\//g, '.');
let def = jsonPath(openApiDocument, refJsonPath);
if (Object.keys(definition).includes('$ref')) {
return getOpenApiDefinitionObject(openApiDocument, def, definitions);
}
return { def, refName: def.title, ignoreInherit };
} else {
const refName = refPath.split('/').splice(-1)[0];
return { def: definitions[refName], refName, ignoreInherit };
}
}
if (Object.keys(definition).includes('oneOf')) {
const openApiDefinitionObject = (definition as OpenApiDefinitionObject).oneOf!.filter((x: any) => x.type != 'null')[0];
return getOpenApiDefinitionObject(openApiDefinitionObject, definitions);
return getOpenApiDefinitionObject(openApiDocument, openApiDefinitionObject, definitions);
}
return { def: definition as OpenApiDefinitionObject, refName: undefined, ignoreInherit };
}

export function getOpenApiDefinitionObjectProps(
openApiDocument: OpenApiDocument,
definitionObj: OpenApiDefinitionObject,
includeInheritProps: boolean,
definitions: OpenApiDefinitionsDictionary,
): { [propName: string]: OpenApiDefinition } {
return getOpenApiDefinitionPropGetter(
openApiDocument,
definitionObj,
includeInheritProps,
definitions,
Expand All @@ -35,6 +48,7 @@ export function getOpenApiDefinitionObjectProps(
}

export function getOpenApiDefinitionPropGetter<T>(
openApiDocument: OpenApiDocument,
definitionObj: OpenApiDefinitionObject,
includeInheritProps: boolean,
definitions: OpenApiDefinitionsDictionary,
Expand All @@ -51,9 +65,9 @@ export function getOpenApiDefinitionPropGetter<T>(
}
let inheritVals = defaultVal;
if (includeInheritProps) {
const refsObjs = (definitionObj.allOf || []).filter(x => Object.keys(x).includes('$ref')).map(x => getOpenApiDefinitionObject(x, definitions));
const refsObjs = (definitionObj.allOf || []).filter(x => Object.keys(x).includes('$ref')).map(x => getOpenApiDefinitionObject(openApiDocument, x, definitions));
for (const x of refsObjs) {
inheritVals = combineVals(inheritVals, getOpenApiDefinitionPropGetter(x.def, true, definitions, getter, getterType));
inheritVals = combineVals(inheritVals, getOpenApiDefinitionPropGetter(openApiDocument, x.def, true, definitions, getter, getterType));
}
}
return combineVals(combineVals(inheritVals, vals2), vals);
Expand Down
5 changes: 4 additions & 1 deletion src/models/editor/EditorArrayInput.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,23 @@
import { OpenApiDefinitionsDictionary } from './../openapi/OpenApiDefinitionsDictionary';
import { OpenApiDefinitionObject } from './../openapi/OpenApiDefinitionObject';
import { EditorInput } from './EditorInput';
import { OpenApiDocument } from './../openapi/OpenApiDocument';

export class EditorArrayInput extends EditorInput {
public itemInput: EditorInput;
public readonly maxItems: number | undefined;
public readonly minItems: number | undefined;
public readonly uniqueItems: boolean | undefined;

constructor(
openApiDocument: OpenApiDocument,
itemInput: EditorInput,
path: string,
openApiDefinition: OpenApiDefinitionObject,
openApiParentDefinition: OpenApiDefinitionObject | undefined,
definitions: OpenApiDefinitionsDictionary | undefined
) {
super(path, 'EditorArrayInput', openApiDefinition, openApiParentDefinition, definitions);
super(openApiDocument, path, 'EditorArrayInput', openApiDefinition, openApiParentDefinition, definitions);
this.itemInput = itemInput;
this.maxItems = openApiDefinition.maxItems;
this.minItems = openApiDefinition.minItems;
Expand Down
5 changes: 4 additions & 1 deletion src/models/editor/EditorInput.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { OpenApiDefinitionsDictionary } from './../openapi/OpenApiDefinitionsDictionary';
import { cloneHelper, editorNameByPath, getOpenApiDefinitionPropGetter } from '../../helpers';
import { OpenApiDefinitionObject } from './../openapi/OpenApiDefinitionObject';
import { OpenApiDocument } from './../openapi/OpenApiDocument';

export class EditorInput {
public path: string;
public name: string;
Expand All @@ -15,6 +17,7 @@ export class EditorInput {
public default: any | undefined;
public className?: string;
constructor(
openApiDocument: OpenApiDocument,
path: string,
editorType: 'EditorArrayInput' | 'EditorObjectInput' | 'EditorPrimitiveInput',
openApiDefinition: OpenApiDefinitionObject,
Expand All @@ -37,7 +40,7 @@ export class EditorInput {
parentClone.properties[this.name]['nullable'] ||
parentClone.properties[this.name]['x-nullable'];
this.editorType = editorType;
const requiredList = getOpenApiDefinitionPropGetter(parentClone, true, definitions || {}, x => (x as OpenApiDefinitionObject)?.required || [], 'array');
const requiredList = getOpenApiDefinitionPropGetter(openApiDocument, parentClone, true, definitions || {}, x => (x as OpenApiDefinitionObject)?.required || [], 'array');
const propName = path.split('.').splice(-1)[0];
this.required = requiredList.includes(propName);
if (path == 'subCategoryCounterSelector' || propName.includes('categoryCounterSelector')) {
Expand Down
4 changes: 3 additions & 1 deletion src/models/editor/EditorObjectInput.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { OpenApiDefinitionsDictionary } from './../openapi/OpenApiDefinitionsDictionary';
import { OpenApiDefinitionObject } from './../openapi/OpenApiDefinitionObject';
import { EditorInput } from './EditorInput';
import { OpenApiDocument } from './../openapi/OpenApiDocument';

export class EditorObjectInput extends EditorInput {
public properties!: EditorInput[];
Expand All @@ -14,14 +15,15 @@ export class EditorObjectInput extends EditorInput {
public readonly definistionName: string;
public implements: string[];
constructor(
openApiDocument: OpenApiDocument,
switchableOptions: string[],
path: string,
definistionName: string,
openApiDefinition: OpenApiDefinitionObject,
openApiParentDefinition: OpenApiDefinitionObject | undefined,
definitions: OpenApiDefinitionsDictionary | undefined
) {
super(path, 'EditorObjectInput', openApiDefinition, openApiParentDefinition, definitions);
super(openApiDocument, path, 'EditorObjectInput', openApiDefinition, openApiParentDefinition, definitions);
this.definistionName = definistionName;
openApiDefinition.anyOf = openApiDefinition.anyOf || [];
this.switchable = openApiDefinition.anyOf.length > 0;
Expand Down
4 changes: 3 additions & 1 deletion src/models/editor/EditorPrimitiveInput.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { OpenApiDefinitionsDictionary } from './../openapi/OpenApiDefinitionsDictionary';
import { OpenApiDefinitionObject } from './../openapi/OpenApiDefinitionObject';
import { EditorInput } from './EditorInput';
import { OpenApiDocument } from './../openapi/OpenApiDocument';

export class EditorPrimitiveInput extends EditorInput {
public readonly type: 'number' | 'date' | 'string' | 'enum' | 'boolean';
Expand All @@ -14,13 +15,14 @@ export class EditorPrimitiveInput extends EditorInput {
public readonly pattern: string | undefined;

constructor(
openApiDocument: OpenApiDocument,
type: 'number' | 'date' | 'string' | 'enum' | 'boolean',
path: string,
openApiDefinition: OpenApiDefinitionObject,
openApiParentDefinition: OpenApiDefinitionObject | undefined,
definitions: OpenApiDefinitionsDictionary | undefined
) {
super(path, 'EditorPrimitiveInput', openApiDefinition, openApiParentDefinition, definitions);
super(openApiDocument, path, 'EditorPrimitiveInput', openApiDefinition, openApiParentDefinition, definitions);
this.enumNames = openApiDefinition['x-enumNames'] || [];
this.enumValues = openApiDefinition.enum || [];
this.pattern = openApiDefinition.pattern;
Expand Down

0 comments on commit 0a7c4b1

Please sign in to comment.