Skip to content

Commit

Permalink
Merge pull request #314 from json-schema-tools/feat/iscycle-working-a…
Browse files Browse the repository at this point in the history
…nd-deps

Feat/iscycle working and deps
  • Loading branch information
BelfordZ authored Jun 18, 2021
2 parents 1a5bbee + 3fdca68 commit 6477322
Show file tree
Hide file tree
Showing 4 changed files with 148 additions and 52 deletions.
145 changes: 108 additions & 37 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,13 @@
"devDependencies": {
"@json-schema-tools/meta-schema": "^1.6.10",
"@types/jest": "^26.0.23",
"@types/node": "^15.12.2",
"@typescript-eslint/eslint-plugin": "^4.26.1",
"@typescript-eslint/parser": "^4.26.1",
"@types/node": "^15.12.3",
"@typescript-eslint/eslint-plugin": "^4.27.0",
"@typescript-eslint/parser": "^4.27.0",
"eslint": "^7.28.0",
"jest": "^26.6.3",
"ts-jest": "^26.5.6",
"typedoc": "^0.20.36",
"typedoc": "^0.20.37",
"typescript": "4.2.4"
},
"dependencies": {}
Expand Down
23 changes: 22 additions & 1 deletion src/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -415,7 +415,7 @@ describe("traverse", () => {
title: "6",
type: "object",
allOf: [
{ title: "7", type: "object", properties: { baz: { title: "8" } } },
{ title: "7", type: "object", properties: { baz: { title: "5" } } },
],
},
},
Expand Down Expand Up @@ -573,6 +573,27 @@ describe("traverse", () => {
expect(mockMutation).toHaveBeenCalledWith(testSchema, true, "");
expect(mockMutation).not.toHaveBeenCalledWith(testSchema, false, "");
});

it("true when the cycle is inside oneOf", () => {
const testSchema = {
title: "a",
oneOf: [{
title: "b",
type: "object",
properties: {
a: {}
}
}]
};
testSchema.oneOf[0].properties.a = testSchema;

const mockMutation = jest.fn((mockS) => mockS);

traverse(testSchema, mockMutation, { mutable: false });

expect(mockMutation).toHaveBeenCalledWith(testSchema, true, "");
expect(mockMutation).not.toHaveBeenCalledWith(testSchema, false, "");
});
});

describe("bfs", () => {
Expand Down
24 changes: 14 additions & 10 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ import { JSONSchema, JSONSchemaObject, PatternProperties } from "@json-schema-to
* Signature of the mutation method passed to traverse.
*
* @param schema The schema or subschema node being traversed
* @param isRootOfCycle false if the schema passed is not the root of a detected cycle. Useful for special handling of cycled schemas.
* @param isCycle false if the schema passed is not the root of a detected cycle. Useful for special handling of cycled schemas.
* @param path json path string separated by periods
*/
export type MutationFunction = (schema: JSONSchema, isRootOfCycle: boolean, path: string, ) => JSONSchema;
export type MutationFunction = (schema: JSONSchema, isCycle: boolean, path: string,) => JSONSchema;

/**
* The options you can use when traversing.
Expand Down Expand Up @@ -74,8 +74,8 @@ export default function traverse(
recursiveStack: JSONSchema[] = [],
pathStack: string[] = [],
prePostMap: Array<[JSONSchema, JSONSchema]> = [],
cycleSet: JSONSchema[] = [],
): JSONSchema {
let isRootOfCycle = false;
const opts = { ...defaultOptions, ...traverseOptions }; // would be nice to make an 'entry' func when we get around to optimizations

// booleans are a bit messed. Since all other schemas are objects (non-primitive type
Expand Down Expand Up @@ -112,7 +112,7 @@ export default function traverse(
const rec = (s: JSONSchema, path: string[]): JSONSchema => {
const foundCycle = isCycle(s, recursiveStack);
if (foundCycle) {
if (foundCycle === schema) { isRootOfCycle = true; }
cycleSet.push(foundCycle);

// if the cycle is a ref to the root schema && skipFirstMutation is try we need to call mutate.
// If we don't, it will never happen.
Expand All @@ -127,6 +127,7 @@ export default function traverse(
return cycledMutableSchema;
}

// else
return traverse(
s,
mutation,
Expand All @@ -135,21 +136,22 @@ export default function traverse(
recursiveStack,
path,
prePostMap,
cycleSet,
);
};

if (schema.anyOf) {
mutableSchema.anyOf = schema.anyOf.map((x,i) => {
mutableSchema.anyOf = schema.anyOf.map((x, i) => {
const result = rec(x, [...pathStack, "anyOf", i.toString()]);
return result;
});
} else if (schema.allOf) {
mutableSchema.allOf = schema.allOf.map((x,i) => {
mutableSchema.allOf = schema.allOf.map((x, i) => {
const result = rec(x, [...pathStack, "allOf", i.toString()]);
return result;
});
} else if (schema.oneOf) {
mutableSchema.oneOf = schema.oneOf.map((x,i) => {
mutableSchema.oneOf = schema.oneOf.map((x, i) => {
const result = rec(x, [...pathStack, "oneOf", i.toString()]);
return result;
});
Expand All @@ -158,14 +160,14 @@ export default function traverse(

if (schema.items) {
if (schema.items instanceof Array) {
mutableSchema.items = schema.items.map((x,i) => {
mutableSchema.items = schema.items.map((x, i) => {
const result = rec(x, [...pathStack, "items", i.toString()]);
return result;
});
} else {
const foundCycle = isCycle(schema.items, recursiveStack);
if (foundCycle) {
if (foundCycle === schema) { isRootOfCycle = true; }
cycleSet.push(foundCycle);

if (opts.skipFirstMutation === true && foundCycle === recursiveStack[0]) {
mutableSchema.items = mutation(schema.items, true, jsonPathStringify(pathStack));
Expand All @@ -186,6 +188,7 @@ export default function traverse(
recursiveStack,
pathStack,
prePostMap,
cycleSet,
);
}
}
Expand Down Expand Up @@ -229,6 +232,7 @@ export default function traverse(
if (opts.bfs === true) {
return mutableSchema;
} else {
return mutation(mutableSchema, isRootOfCycle, jsonPathStringify(pathStack));
const isCycle = cycleSet.indexOf(schema) !== -1
return mutation(mutableSchema, isCycle, jsonPathStringify(pathStack));
}
}

0 comments on commit 6477322

Please sign in to comment.