# json-schema-cycles

> Analyize recursive (cyclic) JSON Schema types

Latest version **3.0.0** (published 2023-02-02) · MIT license · 0 weekly downloads

## Install

```sh
npm install json-schema-cycles
pnpm add json-schema-cycles
yarn add json-schema-cycles
bun add json-schema-cycles
```

## Health

**Score 30/100 (F)** — status: abandoned.

Positive: has types; esm support; no vulnerabilities; high quality score.

Warnings: low downloads.

Negative: abandoned; low maintenance score.

## Facts

| | |
|---|---|
| Version | 3.0.0 |
| Published | 2023-02-02 |
| First published | 2021-04-01 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | bundled |
| Module format | ESM + CommonJS |
| Node | ^14.13.1 \|\| >=16.0.0 |
| Dependencies | 2 |
| Unpacked size | 11 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 5 |
| Author | Gustaf Räntilä |
| Maintainers | grantila |
| Keywords | json, schema, jsonschema, cycles, cyclic, recursive |

## Links

- npm: https://www.npmjs.com/package/json-schema-cycles
- Repository: https://github.com/grantila/json-schema-cycles
- Homepage: https://github.com/grantila/json-schema-cycles#readme
- Issues: https://github.com/grantila/json-schema-cycles/issues
- npm.io page: https://npm.io/package/json-schema-cycles

## Dependencies (2)

- [graph-cycles](https://npm.io/package/graph-cycles.md) ^3.0.0
- [json-schema-traverse](https://npm.io/package/json-schema-traverse.md) ^1.0.0

## Alternatives

- [@mapbox/jsonlint-lines-primitives](https://npm.io/package/@mapbox/jsonlint-lines-primitives.md) — 5.3M weekly downloads
- [reftools](https://npm.io/package/reftools.md) — 3.5M weekly downloads
- [@hey-api/openapi-ts](https://npm.io/package/@hey-api/openapi-ts.md) — 3.5M weekly downloads
- [@mapbox/geojson-rewind](https://npm.io/package/@mapbox/geojson-rewind.md) — 2.4M weekly downloads
- [turbo-stream](https://npm.io/package/turbo-stream.md) — 1.7M weekly downloads

## Recent versions

- 3.0.0 (latest) — 2023-02-02
- 2.0.0 — 2021-10-09
- 1.1.0 — 2021-04-11
- 1.0.0 — 2021-04-01

## README

[![npm version][npm-image]][npm-url]
[![downloads][downloads-image]][npm-url]
[![build status][build-image]][build-url]
[![coverage status][coverage-image]][coverage-url]
[![Node.JS version][node-version]][node-url]


# 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.

There are two types of analysis functions, `analyzeTypes` and `analyzeTypesFast`. The former provides a more in-depth analysis but can be slow on large input. If the input is extremely complex with massive cyclicity, it might even crash the process or run out of memory.

Unless an in-depth analysis is necessary, choose the `analyzeTypesFast` function.


## Versions

 * Since v2 this is a [pure ESM][pure-esm] package, and requires Node.js >=12.20. It cannot be used from CommonJS.


## Example

`analyzeTypes` takes a JSON schema object and returns a result object on the same format as [`FullAnalysisResult` in graph-cycles](https://github.com/grantila/graph-cycles/#full-analysis-mode) 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.

`analyzeTypesFast` also takes a JSON schema object, but returns an object on the same format as [`FastAnalysisResult` in graph-cycles](https://github.com/grantila/graph-cycles/#fast-analysis-mode), with the same additional `graph` property as from `analyzeTypes`.

```ts
import { analyzeTypes, analyzeTypesFast } from 'json-schema-cycles'

const { cycles, entrypoints, dependencies, dependents, all, graph } = analyzeTypes( schemaObject );
// or
const { cyclic, dependencies, dependents, graph } = analyzeTypesFast( schemaObject );
```

Check [graph-cycles](https://github.com/grantila/graph-cycles) for an understanding of the result object, apart from `graph`.

<details style="padding-left: 32px; border-left: 4px solid gray;">
<summary>Given the following JSON Schema:</summary>
<p>

```ts
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' },
        },
    }
};
```

</p>
</details>

... which can be viewed as:

```
Cart -> Product
                 __       ___
                |  |     |   |
                v  |     v   |
Action -> DM -> User -> Message -> Link
                  ^        |
                  |        v
                  `--- Subscriber

```

for a full analysis, the result will be (of the type `TypeAnalysisFullResult`):

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

for a fast analysis, the result will be (of the type `TypeAnalysisFastResult`):

```ts
{
    cyclic: [ 'User', 'Message', 'DM', 'Actions', 'Subscriber' ],
    dependencies: [ 'Link' ],
    dependents: [ ],
    graph: [
        [ 'Link', [ ] ],
        [ 'Subscriber', [ 'User' ] ],
        [ 'Message', [ 'Message', 'Link', 'Subscriber' ] ],
        [ 'User', [ 'Message', 'User' ] ],
        [ 'DM', [ 'User' ] ],
        [ 'Actions', [ 'DM' ] ],
        [ 'Product', [ ] ],
        [ 'Cart', [ 'Product' ] ],
    ],
}
```


## Helpers

Two helper functions are exported; `sortTypeAnalysisFullResult` and `sortTypeAnalysisFastResult`. They take an analysis result (of type `TypeAnalysisFullResult` or `TypeAnalysisFastResult`) and return a new object of the same type, with all fields sorted in a deterministic way, which is useful in tests.



[npm-image]: https://img.shields.io/npm/v/json-schema-cycles.svg
[npm-url]: https://npmjs.org/package/json-schema-cycles
[downloads-image]: https://img.shields.io/npm/dm/json-schema-cycles.svg
[build-image]: https://img.shields.io/github/actions/workflow/status/grantila/json-schema-cycles/master.yml?branch=master
[build-url]: https://github.com/grantila/json-schema-cycles/actions?query=workflow%3AMaster
[coverage-image]: https://coveralls.io/repos/github/grantila/json-schema-cycles/badge.svg?branch=master
[coverage-url]: https://coveralls.io/github/grantila/json-schema-cycles?branch=master
[node-version]: https://img.shields.io/node/v/json-schema-cycles
[node-url]: https://nodejs.org/en/
[pure-esm]: https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c

---
_Source: https://npm.io/package/json-schema-cycles · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
