Minor refactoring of schema provider
This commit is contained in:
@@ -78,6 +78,18 @@ export const jsonschemaProvider = {
|
||||
}
|
||||
}
|
||||
|
||||
const getResourceSchema = async (resourceName: string): Promise<CrudRJSFSchema> => {
|
||||
return buildResource(await getJsonschema(), resourceName)
|
||||
}
|
||||
|
||||
const getColumns = async (resourceName: string): Promise<GridColDef[]> => {
|
||||
return buildColumns(await getJsonschema(), resourceName)
|
||||
}
|
||||
|
||||
const getFilters = async (resourceName: string, resourcePath: string): Promise<FilterField[]> => {
|
||||
return buildFilters(await getJsonschema(), resourceName, resourcePath);
|
||||
}
|
||||
|
||||
type PathParameter = {
|
||||
in: string,
|
||||
name:string
|
||||
@@ -87,10 +99,6 @@ type PathSchema = {
|
||||
parameters: PathParameter[]
|
||||
}
|
||||
|
||||
function shortenResourceName(resourceName: string) {
|
||||
return convertCamelToSnake(resourceName.replace(/(-Input|-Output|Create|Update|Read)$/g, ""));
|
||||
}
|
||||
|
||||
type FilterField = {
|
||||
name: string,
|
||||
label: string,
|
||||
@@ -98,6 +106,11 @@ type FilterField = {
|
||||
operators: { name: string, label: string }[]
|
||||
}
|
||||
|
||||
type Operator = {
|
||||
operator: string,
|
||||
fieldName: string,
|
||||
}
|
||||
|
||||
async function hasSearch(resourcePath: string): Promise<boolean> {
|
||||
const jst = new JsonSchemaTraverser(await getJsonschema());
|
||||
const pathSchema = jst.getPath(resourcePath);
|
||||
@@ -110,9 +123,9 @@ async function hasSearch(resourcePath: string): Promise<boolean> {
|
||||
return false
|
||||
}
|
||||
|
||||
async function getFilters(resourceName: string, resourcePath: string): Promise<FilterField[]> {
|
||||
function buildFilters(rawSchema: RJSFSchema, resourceName: string, resourcePath: string): FilterField[] {
|
||||
const shortResourceName = shortenResourceName(resourceName);
|
||||
const jst = new JsonSchemaTraverser(await getJsonschema());
|
||||
const jst = new JsonSchemaTraverser(rawSchema);
|
||||
const pathSchema = jst.getPath(resourcePath);
|
||||
|
||||
const seen: { [k: string]: number } = {};
|
||||
@@ -125,8 +138,8 @@ async function getFilters(resourceName: string, resourcePath: string): Promise<F
|
||||
const field = jst.getPropertyByPath(jst.getResource(`${resourceName}Read`), fieldName)
|
||||
filters.push({
|
||||
name: fieldName,
|
||||
label: i18n.t(`schemas.${shortResourceName}.${convertCamelToSnake(fieldName)}`),
|
||||
type: getFieldType(fieldName, field),
|
||||
label: getPropertyI18nLabel(shortResourceName, fieldName),
|
||||
type: getFieldFilterType(fieldName, field),
|
||||
operators: [{ name: operator, label: operator }]
|
||||
});
|
||||
} else {
|
||||
@@ -139,12 +152,6 @@ async function getFilters(resourceName: string, resourcePath: string): Promise<F
|
||||
return filters;
|
||||
}
|
||||
|
||||
|
||||
type Operator = {
|
||||
operator: string,
|
||||
fieldName: string,
|
||||
}
|
||||
|
||||
function processParamName(param: PathParameter): Operator {
|
||||
const nameParts = param.name.split("__")
|
||||
|
||||
@@ -154,7 +161,7 @@ function processParamName(param: PathParameter): Operator {
|
||||
}
|
||||
}
|
||||
|
||||
const getFieldType = (fieldName: string, field: RJSFSchema): string => {
|
||||
const getFieldFilterType = (fieldName: string, field: RJSFSchema): string => {
|
||||
if (fieldName == "created_by" || fieldName == "updated_by") {
|
||||
return "author";
|
||||
} else if (Array.isArray(field)) {
|
||||
@@ -180,17 +187,11 @@ const getFieldType = (fieldName: string, field: RJSFSchema): string => {
|
||||
throw "Unimplemented field type"
|
||||
}
|
||||
|
||||
const getColumns = async (resourceName: string): Promise<GridColDef[]> => {
|
||||
return buildColumns(await getJsonschema(), resourceName)
|
||||
}
|
||||
|
||||
function buildColumns (rawSchemas: RJSFSchema, resourceName: string, prefix: string|undefined = undefined): GridColDef[] {
|
||||
if (rawSchemas.components.schemas[resourceName] === undefined) {
|
||||
throw new Error(`Resource "${resourceName}" not found in schema.`);
|
||||
}
|
||||
const shortResourceName = shortenResourceName(resourceName);
|
||||
const jst = new JsonSchemaTraverser(rawSchemas);
|
||||
let resource = structuredClone(jst.getResource(resourceName));
|
||||
|
||||
const shortResourceName = convertCamelToSnake(resourceName.replace(/(-Input|-Output|Create|Update|Read)$/g, ""));
|
||||
let resource = rawSchemas.components.schemas[resourceName];
|
||||
let result: GridColDef[] = [];
|
||||
for (const prop_name in resource.properties) {
|
||||
let prop = resource.properties[prop_name];
|
||||
@@ -264,42 +265,32 @@ function buildColumns (rawSchemas: RJSFSchema, resourceName: string, prefix: str
|
||||
return result;
|
||||
}
|
||||
|
||||
const getResourceSchema = async (resourceName: string): Promise<CrudRJSFSchema> => {
|
||||
return buildResource(await getJsonschema(), resourceName)
|
||||
}
|
||||
|
||||
function convertCamelToSnake(str: string): string {
|
||||
return str.replace(/([a-zA-Z])(?=[A-Z])/g,'$1_').toLowerCase()
|
||||
}
|
||||
|
||||
function buildResource(rawSchemas: RJSFSchema, resourceName: string) {
|
||||
if (rawSchemas.components.schemas[resourceName] === undefined) {
|
||||
throw new Error(`Resource "${resourceName}" not found in schema.`);
|
||||
}
|
||||
const shortResourceName = shortenResourceName(resourceName);
|
||||
const jst = new JsonSchemaTraverser(rawSchemas);
|
||||
let resource = structuredClone(jst.getResource(resourceName));
|
||||
|
||||
const shortResourceName = convertCamelToSnake(resourceName.replace(/(-Input|-Output|Create|Update|Read)$/g, ""));
|
||||
let resource = structuredClone(rawSchemas.components.schemas[resourceName]);
|
||||
resource.components = { schemas: {} };
|
||||
for (let prop_name in resource.properties) {
|
||||
let prop = resource.properties[prop_name];
|
||||
|
||||
if (is_reference(prop)) {
|
||||
resolveReference(rawSchemas, resource, prop);
|
||||
buildReference(rawSchemas, resource, prop);
|
||||
} else if (is_union(prop)) {
|
||||
const union = prop.hasOwnProperty("oneOf") ? prop.oneOf : prop.anyOf;
|
||||
for (let i in union) {
|
||||
if (is_reference(union[i])) {
|
||||
resolveReference(rawSchemas, resource, union[i]);
|
||||
buildReference(rawSchemas, resource, union[i]);
|
||||
}
|
||||
}
|
||||
} else if (is_enum(prop)) {
|
||||
for (let i in prop.allOf) {
|
||||
if (is_reference(prop.allOf[i])) {
|
||||
resolveReference(rawSchemas, resource, prop.allOf[i]);
|
||||
buildReference(rawSchemas, resource, prop.allOf[i]);
|
||||
}
|
||||
}
|
||||
} else if (is_array(prop) && is_reference(prop.items)) {
|
||||
resolveReference(rawSchemas, resource, prop.items);
|
||||
buildReference(rawSchemas, resource, prop.items);
|
||||
}
|
||||
|
||||
if (prop.hasOwnProperty("title")) {
|
||||
@@ -313,16 +304,7 @@ function buildResource(rawSchemas: RJSFSchema, resourceName: string) {
|
||||
return resource;
|
||||
}
|
||||
|
||||
let rawSchema: RJSFSchema;
|
||||
const getJsonschema = async (): Promise<RJSFSchema> => {
|
||||
if (rawSchema === undefined) {
|
||||
const response = await fetch(`${API_URL}/openapi.json`,);
|
||||
rawSchema = await response.json();
|
||||
}
|
||||
return rawSchema;
|
||||
}
|
||||
|
||||
function resolveReference(rawSchemas: RJSFSchema, resource: any, prop_reference: any) {
|
||||
function buildReference(rawSchemas: RJSFSchema, resource: any, prop_reference: any) {
|
||||
const subresourceName = get_reference_name(prop_reference);
|
||||
const subresource = buildResource(rawSchemas, subresourceName);
|
||||
resource.components.schemas[subresourceName] = subresource;
|
||||
@@ -391,6 +373,31 @@ function get_reference_name(prop: any) {
|
||||
return prop['$ref'].substring(prop['$ref'].lastIndexOf('/')+1);
|
||||
}
|
||||
|
||||
function convertCamelToSnake(str: string): string {
|
||||
return str.replace(/([a-zA-Z])(?=[A-Z])/g,'$1_').toLowerCase()
|
||||
}
|
||||
|
||||
function shortenResourceName(resourceName: string) {
|
||||
return convertCamelToSnake(resourceName.replace(/(-Input|-Output|Create|Update|Read)$/g, ""));
|
||||
}
|
||||
|
||||
function getPropertyI18nLabel(shortResourceName: string, fieldName: string): string {
|
||||
if (meta_fields.indexOf(fieldName) > -1) {
|
||||
return i18n.t(`schemas.${convertCamelToSnake(fieldName)}`);
|
||||
}
|
||||
const path = `schemas.${shortResourceName}.${convertCamelToSnake(fieldName)}`
|
||||
return i18n.t(path)
|
||||
}
|
||||
|
||||
let rawSchema: RJSFSchema;
|
||||
const getJsonschema = async (): Promise<RJSFSchema> => {
|
||||
if (rawSchema === undefined) {
|
||||
const response = await fetch(`${API_URL}/openapi.json`,);
|
||||
rawSchema = await response.json();
|
||||
}
|
||||
return rawSchema;
|
||||
}
|
||||
|
||||
const JsonSchemaTraverser = class {
|
||||
private rawSchemas: RJSFSchema;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user