Skip to content

Commit

Permalink
fix(): update subsetSchema (#1386)
Browse files Browse the repository at this point in the history
  • Loading branch information
jordantsanz authored Jan 17, 2024
1 parent 17e228d commit b1be3e2
Show file tree
Hide file tree
Showing 2 changed files with 180 additions and 52 deletions.
46 changes: 38 additions & 8 deletions packages/common/src/core/schemas/internal/subsetSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { IConfigurationSchema } from "../types";
* @param schema
* @param props
* @returns
*
*/
export function subsetSchema(
schema: IConfigurationSchema,
Expand All @@ -14,15 +15,44 @@ export function subsetSchema(
const subset: IConfigurationSchema = cloneObject(schema);

// 1. remove un-specified properties from the "required" array
subset.required = [...subset.required].filter((required) =>
props.includes(required)
);
if (subset.required) {
subset.required = [...subset.required].filter((required) =>
props.includes(required)
);
}

// 2. filter the rest of the schema down to the specified properties
Object.keys(subset.properties).forEach((key) => {
if (props.indexOf(key) === -1) {
delete subset.properties[key];
}
});
if (subset.properties) {
Object.keys(subset.properties).forEach((key) => {
if (props.indexOf(key) === -1) {
delete subset.properties[key];
}
});
}

// 3. filter schema compositions (anyOf, allOf, oneOf) down
// to specified properties

// TODO: enhance subset functionality to filter more complex
// compositional schemas (anyOf, oneOf) and non-if/then/else conditional structures.
// Also enhance to account for whole compositions versus individual clauses.

if (subset.allOf) {
subset.allOf = subset.allOf.map((s) =>
subsetSchema(s as IConfigurationSchema, props)
);
}

if (subset.if) {
subset.if = subsetSchema(subset.if as IConfigurationSchema, props);
}

if (subset.then) {
subset.then = subsetSchema(subset.then as IConfigurationSchema, props);
}

if (subset.else) {
subset.else = subsetSchema(subset.else as IConfigurationSchema, props);
}
return subset;
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,57 +6,155 @@ import {

describe("filterSchemaToUiSchema util:", () => {
it("returns schema limited to props in UiSchema", () => {
const schema: IConfigurationSchema = {
required: ["name"],
type: "object",
properties: {
name: {
type: "string",
minLength: 1,
maxLength: 250,
},
summary: {
type: "string",
},
description: {
type: "string",
},
},
};

const SteppedUiSchema: IUiSchema = {
type: "Layout",
elements: [
{
type: "Section",
labelKey: "section1.label.key",
options: {
section: "stepper",
open: true,
},
elements: [
{
type: "Step",
labelKey: "step1.label.key",
elements: [
{
labelKey: "property1.label.key",
scope: "/properties/name",
type: "Control",
},
{
labelKey: "property2.label.key",
scope: "/properties/summary",
type: "Control",
},
],
},
],
},
],
};
const chk = filterSchemaToUiSchema(schema, SteppedUiSchema);
expect(chk.properties?.description).not.toBeDefined();
});
});

const schema: IConfigurationSchema = {
required: ["name"],
type: "object",
properties: {
name: {
type: "string",
minLength: 1,
maxLength: 250,
},
summary: {
type: "string",
},
description: {
type: "string",
},
},
};

const SteppedUiSchema: IUiSchema = {
type: "Layout",
elements: [
{
type: "Section",
labelKey: "section1.label.key",
options: {
section: "stepper",
open: true,
it("returns schema limited to props in UiSchema when there is a conditional that does not apply", () => {
const schema: IConfigurationSchema = {
required: ["title"],
properties: {
status: {
type: "string",
},
groups: {
type: "array",
},
title: {
type: "string",
},
_metric: {
type: "object",
properties: {
type: {
type: "string",
enum: ["static", "dynamic"],
},
value: {
type: "string",
},
},
},
},
elements: [
allOf: [
{
type: "Step",
labelKey: "step1.label.key",
elements: [
{
labelKey: "property1.label.key",
scope: "/properties/name",
type: "Control",
if: {
properties: {
_metric: {
properties: {
type: {
const: "static",
},
},
},
},
{
labelKey: "property2.label.key",
scope: "/properties/summary",
type: "Control",
},
then: {
properties: {
_metric: {
required: ["value"],
},
},
],
},
else: {
required: ["status"],
},
},
],
};

const uiSchema: IUiSchema = {
type: "Layout",
elements: [
{
type: "Control",
scope: "/properties/title",
labelKey: "title",
},
{
type: "Control",
scope: "/properties/status",
labelKey: "status",
},
{
type: "Control",
scope: "/properties/groups",
labelKey: "groups",
},
],
},
],
};
};

const chk = filterSchemaToUiSchema(schema, uiSchema);
expect(chk).toEqual({
required: ["title"],
properties: {
status: {
type: "string",
},
groups: {
type: "array",
},
title: {
type: "string",
},
},
allOf: [
{
if: { properties: {} },
then: { properties: {} },
else: { required: ["status"] },
},
],
});
expect(chk.properties?._metric).not.toBeDefined();
});
});

0 comments on commit b1be3e2

Please sign in to comment.