Skip to content

grantila/json-schema-cycles

Repository files navigation

npm version downloads build status coverage status Language grade: JavaScript Node.JS version

json-schema-cycles

Detect cyclic dependencies in a JSON schema (or more precisely a JSON schema with the definitions property for the individual type definitions). This package doesn't handle external references, you need to use a ref-parser and squash all types into one schema before using this package.

Example

json-schema-cycles exports a function analyzeTypes which takes a JSON schema object and returns a result object on the same format as AnalysisResult in graph-cycles but with an additional graph property containing the type dependency graph as an array of [ from: string, to: Array< string > ] where from is the type and to is the dependent types.

import { analyzeTypes } from 'json-schema-cycles'

const { cycles, entrypoints, dependencies, all, graph } = analyzeTypes( schemaObject );

Check graph-cycles for an understanding of the result object, apart from graph.

Given the following JSON Schema:

const jsonSchema = {
    definitions: {
        Link: {}, // Non-cyclic but dependency of Message
        Subscriber: {
            type: 'object',
            properties: {
                user: { $ref: '#/definitions/User' },
            },
        },
        Message: {
            type: 'object',
            properties: {
                replyTo: { $ref: '#/definitions/Message' },
                link: { $ref: '#/definitions/Link' },
                subscriber: { $ref: '#/definitions/Subscriber' },
            },
        },
        User: {
            type: 'object',
            properties: {
                parent: { $ref: '#/definitions/User' },
                lastMessage: { $ref: '#/definitions/Message' },
            },
        },
        DM: {
            type: 'object',
            properties: {
                lastUser: { $ref: '#/definitions/User' },
            },
        },
        Actions: {
            type: 'object',
            properties: {
                dms: {
                    type: 'array',
                    items: { $ref: '#/definitions/DM' },
                },
            },
        },
        // Has dependencies, but nothing cyclic
        Product: {},
        Cart: {
            type: 'array',
            items: { $ref: '#/definitions/Product' },
        },
    }
};

the analysis will be:

{
    entrypoints: [
        [ "DM" ],
        [ "Actions", "DM" ],
    ],
    cycles: [
        [ 'User' ],
        [ 'Message' ],
        [ 'User', 'Message', 'Subscriber' ],
    ],
    all: [ 'User', 'Message', 'DM', 'Actions', 'Subscriber' ],
    dependencies: [ "Link" ],
    graph: [
        [ 'Link', [ ] ],
        [ 'Subscriber', [ 'User' ] ],
        [ 'Message', [ 'Message', 'Link', 'Subscriber' ] ],
        [ 'User', [ 'Message', 'User' ] ],
        [ 'DM', [ 'User' ] ],
        [ 'Actions', [ 'DM' ] ],
        [ 'Product', [ ] ],
        [ 'Cart', [ 'Product' ] ],
    ],
}

Helper

Another function sortTypeAnalysisResult is exported, which takes an analysis result (of type TypeAnalysisResult) and returns new object of the same type, with all fields sorted in a deterministic way, which is useful in tests.

About

Analyize recursive (cyclic) JSON Schema types

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published