Skip to content

Commit

Permalink
feat(ui): handle allOf schemas
Browse files Browse the repository at this point in the history
  • Loading branch information
timonback committed May 19, 2024
1 parent ee1de1c commit af5a27d
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 18 deletions.
77 changes: 61 additions & 16 deletions springwolf-ui/src/app/service/asyncapi/asyncapi-mapper.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,18 @@
import { AsyncApi } from "../../models/asyncapi.model";
import { Server } from "../../models/server.model";
import {
ChannelOperation,
CHANNEL_ANCHOR_PREFIX,
ChannelOperation,
} from "../../models/channel.model";
import { Schema } from "../../models/schema.model";
import { Injectable } from "@angular/core";
import { Example } from "../../models/example.model";
import { Info } from "../../models/info.model";
import { ServerAsyncApi } from "./models/asyncapi.model";
import { ServerAsyncApiSchema } from "./models/schema.model";
import {
ServerAsyncApiSchema,
ServerAsyncApiSchemaOrRef,
} from "./models/schema.model";
import { ServerBinding, ServerBindings } from "./models/bindings.model";
import {
ServerOperation,
Expand Down Expand Up @@ -252,44 +255,54 @@ export class AsyncApiMapperService {
private mapSchemas(
schemas: ServerComponents["schemas"]
): Map<string, Schema> {
const s = new Map<string, Schema>();
Object.entries(schemas).forEach(([k, v]) => {
const schema = this.parsingErrorBoundary("schema with name " + k, () =>
this.mapSchema(k, v)
const mappedSchemas = new Map<string, Schema>();
Object.entries(schemas).forEach(([schemaName, schema]) => {
const mappedSchema = this.parsingErrorBoundary(
"schema with name " + schemaName,
() => this.mapSchema(schemaName, schema, schemas)
);

if (schema != undefined) {
s.set(k, schema);
if (mappedSchema != undefined) {
mappedSchemas.set(schemaName, mappedSchema);
}
});
return s;
return mappedSchemas;
}

private mapSchema(
schemaName: string,
schema: ServerAsyncApiSchema | { $ref: string }
schema: ServerAsyncApiSchemaOrRef,
schemas: ServerComponents["schemas"]
): Schema {
if ("$ref" in schema) {
return this.mapSchemaRef(schemaName, schema);
} else {
return this.mapSchemaObj(schemaName, schema);
return this.mapSchemaObj(schemaName, schema, schemas);
}
}

private mapSchemaObj(
schemaName: string,
schema: ServerAsyncApiSchema
schema: ServerAsyncApiSchema,
schemas: ServerComponents["schemas"]
): Schema {
const properties = {};
if (schema.properties !== undefined) {
Object.entries(schema.properties).forEach(([key, value], index) => {
properties[key] = this.mapSchema(key, value);
this.addPropertiesToSchema(schema, properties, schemas);
if (schema.allOf !== undefined) {
schema.allOf.forEach((schema, index) => {
this.addPropertiesToSchema(schema, properties, schemas);
});
}
if (schema.anyOf !== undefined && schema.oneOf.length > 0) {
this.addPropertiesToSchema(schema.anyOf[0], properties, schemas);
}
if (schema.oneOf !== undefined && schema.oneOf.length > 0) {
this.addPropertiesToSchema(schema.oneOf[0], properties, schemas);
}

const items =
schema.items !== undefined
? this.mapSchema(schemaName + "[]", schema.items)
? this.mapSchema(schemaName + "[]", schema.items, schemas)
: undefined;
const example =
schema.examples !== undefined && 0 < schema.examples.length
Expand Down Expand Up @@ -325,6 +338,38 @@ export class AsyncApiMapperService {
};
}

private addPropertiesToSchema(
schema: ServerAsyncApiSchemaOrRef,
properties: {},
schemas: ServerComponents["schemas"]
) {
let actualSchema = this.resolveSchema(schema, schemas);

if ("properties" in actualSchema) {
Object.entries(actualSchema.properties).forEach(([key, value], index) => {
properties[key] = this.mapSchema(key, value, schemas);
});
}
}

private resolveSchema(
schema: ServerAsyncApiSchemaOrRef,
schemas: ServerComponents["schemas"]
): ServerAsyncApiSchema {
let actualSchema = schema;

while ("$ref" in actualSchema) {
const refName = this.resolveRef(actualSchema.$ref);
const refSchema = schemas[refName];
if (refSchema !== undefined) {
actualSchema = refSchema;
} else {
return undefined;
}
}
return actualSchema;
}

private mapSchemaRef(schemaName: string, schema: { $ref: string }): Schema {
return {
name: schemaName,
Expand Down
11 changes: 9 additions & 2 deletions springwolf-ui/src/app/service/asyncapi/models/schema.model.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,20 @@
/* SPDX-License-Identifier: Apache-2.0 */
export type ServerAsyncApiSchemaOrRef = ServerAsyncApiSchema | { $ref: string };

export interface ServerAsyncApiSchema {
description?: string;
type: string;
format?: string;
enum?: string[];

properties?: {
[key: string]: ServerAsyncApiSchema | { $ref: string };
[key: string]: ServerAsyncApiSchemaOrRef;
};
items?: ServerAsyncApiSchema | { $ref: string };
allOf?: ServerAsyncApiSchemaOrRef[];
anyOf?: ServerAsyncApiSchemaOrRef[];
oneOf?: ServerAsyncApiSchemaOrRef[];

items?: ServerAsyncApiSchemaOrRef;
examples?: any[];

required?: string[];
Expand Down

0 comments on commit af5a27d

Please sign in to comment.