schematized
Advanced tools
Comparing version 1.4.0 to 1.5.0
@@ -5,7 +5,7 @@ export declare class SchemaBuilder { | ||
constructor(schemaUri?: string); | ||
addObject(object: Record<string, unknown>): void; | ||
addObject(object: Record<string, any>): void; | ||
addSchema(schema: Record<string, any>): void; | ||
toSchema(): any; | ||
toJson(): string; | ||
toPrettySchema(): string; | ||
private baseSchema; | ||
} |
"use strict"; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.SchemaBuilder = void 0; | ||
const schema_node_1 = require("./schema-node"); | ||
const lodash_1 = __importDefault(require("lodash")); | ||
const DEFAULT_URI = 'http://json-schema.org/schema#'; | ||
class SchemaBuilder { | ||
constructor(schemaUri = 'http://json-schema.org/schema#') { | ||
constructor(schemaUri = 'http://json-schema.org/draft-07/schema#') { | ||
this.schemaUri = schemaUri; | ||
@@ -19,17 +14,8 @@ this.rootNode = new schema_node_1.SchemaNode(); | ||
addSchema(schema) { | ||
if (schema instanceof SchemaBuilder) { | ||
const schemaUri = schema.schemaUri; | ||
if (schema instanceof SchemaBuilder || schema instanceof schema_node_1.SchemaNode) { | ||
schema = schema.toSchema(); | ||
if (lodash_1.default.isNil(schemaUri)) { | ||
delete schema.$schema; | ||
} | ||
} | ||
else if (schema instanceof schema_node_1.SchemaNode) { | ||
schema = schema.toSchema(); | ||
if (!this.schemaUri && schema.$schema) { | ||
this.schemaUri = schema.$schema; | ||
} | ||
if (lodash_1.default.includes(schema, '$schema')) { | ||
this.schemaUri = this.schemaUri || schema.$schema; | ||
schema = lodash_1.default.clone(schema); | ||
delete schema.$schema; | ||
} | ||
this.rootNode.addSchema(schema); | ||
@@ -39,12 +25,9 @@ } | ||
const schema = this.baseSchema(); | ||
return lodash_1.default.merge(schema, this.rootNode.toSchema()); | ||
return { ...schema, ...this.rootNode.toSchema() }; | ||
} | ||
toJson() { | ||
toPrettySchema() { | ||
return JSON.stringify(this.toSchema(), null, 2); | ||
} | ||
baseSchema() { | ||
if (this.schemaUri === 'null') { | ||
return {}; | ||
} | ||
return { $schema: this.schemaUri || DEFAULT_URI }; | ||
return { $schema: this.schemaUri }; | ||
} | ||
@@ -51,0 +34,0 @@ } |
export declare class SchemaNode { | ||
activeStrategies: any; | ||
strategies: typeof import("./strategies/scalar").Boolean[]; | ||
strategies: typeof import("./strategies/boolean").BooleanStrategy[]; | ||
constructor(); | ||
addSchema(schema: Record<string, unknown>): this; | ||
addSchema(schema: Record<string, any>): this; | ||
addObject(object: Record<string, unknown>): this; | ||
@@ -7,0 +7,0 @@ toSchema(): any; |
@@ -43,3 +43,3 @@ "use strict"; | ||
} | ||
if (lodash_1.default.size(types) > 0) { | ||
if (types.size > 0) { | ||
let schemaType; | ||
@@ -90,3 +90,3 @@ if (types.size === 1) { | ||
this.activeStrategies[this.activeStrategies.length - 1] instanceof | ||
strategies_1.Typeless) { | ||
strategies_1.TypelessStrategy) { | ||
const typeless = this.activeStrategies.pop(); | ||
@@ -100,3 +100,3 @@ activeStrategy.addSchema(typeless.toSchema()); | ||
// No match found, if typeless add to first strategy | ||
const typelessInstance = new strategies_1.Typeless(schemaNode); | ||
const typelessInstance = new strategies_1.TypelessStrategy(schemaNode); | ||
if (kind === 'schema' && typelessInstance.matchSchema(schemaOrObject)) { | ||
@@ -103,0 +103,0 @@ if (this.activeStrategies.length === 0) { |
@@ -1,3 +0,3 @@ | ||
import { Boolean } from './scalar'; | ||
export declare const BASIC_SCHEMA_STRATEGIES: (typeof Boolean)[]; | ||
export { Typeless } from './scalar'; | ||
import { BooleanStrategy } from './boolean'; | ||
export declare const BASIC_SCHEMA_STRATEGIES: (typeof BooleanStrategy)[]; | ||
export { TypelessStrategy } from './typeless'; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.BASIC_SCHEMA_STRATEGIES = void 0; | ||
const scalar_1 = require("./scalar"); | ||
const array_1 = require("./array"); | ||
const boolean_1 = require("./boolean"); | ||
const null_1 = require("./null"); | ||
const number_1 = require("./number"); | ||
@@ -10,6 +11,5 @@ const object_1 = require("./object"); | ||
exports.BASIC_SCHEMA_STRATEGIES = [ | ||
scalar_1.Boolean, | ||
scalar_1.Null, | ||
boolean_1.BooleanStrategy, | ||
null_1.NullStrategy, | ||
number_1.NumberStrategy, | ||
scalar_1.Integer, | ||
string_1.StringStrategy, | ||
@@ -19,4 +19,4 @@ array_1.ArrayStrategy, | ||
]; | ||
var scalar_2 = require("./scalar"); | ||
Object.defineProperty(exports, "Typeless", { enumerable: true, get: function () { return scalar_2.Typeless; } }); | ||
var typeless_1 = require("./typeless"); | ||
Object.defineProperty(exports, "TypelessStrategy", { enumerable: true, get: function () { return typeless_1.TypelessStrategy; } }); | ||
//# sourceMappingURL=index.js.map |
import { Maximum } from './maximum'; | ||
import { Minimum } from './minimum'; | ||
import { TypedSchemaStrategy } from '../base'; | ||
import { TypedSchemaStrategy } from '../typed-schema-strategy'; | ||
export declare class NumberStrategy extends TypedSchemaStrategy { | ||
@@ -5,0 +5,0 @@ type: string; |
@@ -9,5 +9,5 @@ "use strict"; | ||
const minimum_1 = require("./minimum"); | ||
const base_1 = require("../base"); | ||
const typed_schema_strategy_1 = require("../typed-schema-strategy"); | ||
const lodash_1 = __importDefault(require("lodash")); | ||
class NumberStrategy extends base_1.TypedSchemaStrategy { | ||
class NumberStrategy extends typed_schema_strategy_1.TypedSchemaStrategy { | ||
constructor(schemaNode) { | ||
@@ -14,0 +14,0 @@ super(schemaNode); |
export declare class Maximum { | ||
keywords: Set<string>; | ||
max: number | null; | ||
addObject(number: number): void; | ||
addSchema(schema: Record<string, any>): void; | ||
addObject(number: number): void; | ||
toSchema(): { | ||
@@ -7,0 +7,0 @@ maximum: number; |
@@ -13,2 +13,5 @@ "use strict"; | ||
} | ||
addObject(number) { | ||
this.max = lodash_1.default.isNil(this.max) ? number : Math.max(this.max, number); | ||
} | ||
addSchema(schema) { | ||
@@ -22,5 +25,2 @@ if (lodash_1.default.isNil(this.max)) { | ||
} | ||
addObject(number) { | ||
this.max = lodash_1.default.isNil(this.max) ? number : Math.max(this.max, number); | ||
} | ||
toSchema() { | ||
@@ -27,0 +27,0 @@ return { maximum: this.max }; |
export declare class Minimum { | ||
keywords: Set<string>; | ||
min: number | null; | ||
addObject(number: number): void; | ||
addSchema(schema: Record<string, any>): void; | ||
addObject(number: number): void; | ||
toSchema(): { | ||
@@ -7,0 +7,0 @@ minimum: number; |
@@ -13,2 +13,5 @@ "use strict"; | ||
} | ||
addObject(number) { | ||
this.min = lodash_1.default.isNil(this.min) ? number : Math.min(this.min, number); | ||
} | ||
addSchema(schema) { | ||
@@ -22,5 +25,2 @@ if (lodash_1.default.isNil(this.min)) { | ||
} | ||
addObject(number) { | ||
this.min = lodash_1.default.isNil(this.min) ? number : Math.min(this.min, number); | ||
} | ||
toSchema() { | ||
@@ -27,0 +27,0 @@ return { minimum: this.min }; |
export declare class Format { | ||
keywords: Set<string>; | ||
format: string | null; | ||
addObject(string: string): void; | ||
addSchema(schema: Record<string, any>): void; | ||
addObject(string: string): void; | ||
toSchema(): Record<string, unknown>; | ||
} |
@@ -13,2 +13,7 @@ "use strict"; | ||
} | ||
addObject(string) { | ||
this.format = lodash_1.default.isNil(this.format) | ||
? Object.keys(formats).find((f) => formats[f].test(string)) | ||
: this.format; | ||
} | ||
addSchema(schema) { | ||
@@ -22,7 +27,2 @@ if (lodash_1.default.isNil(this.format)) { | ||
} | ||
addObject(string) { | ||
this.format = lodash_1.default.isNil(this.format) | ||
? Object.keys(formats).find((f) => formats[f].test(string)) | ||
: this.format; | ||
} | ||
toSchema() { | ||
@@ -29,0 +29,0 @@ if (!this.format) |
import { Format } from './format'; | ||
import { MaxLength } from './max-length'; | ||
import { MinLength } from './min-length'; | ||
import { TypedSchemaStrategy } from '../base'; | ||
import { TypedSchemaStrategy } from '../typed-schema-strategy'; | ||
export declare class StringStrategy extends TypedSchemaStrategy { | ||
@@ -6,0 +6,0 @@ type: string; |
@@ -10,5 +10,5 @@ "use strict"; | ||
const min_length_1 = require("./min-length"); | ||
const base_1 = require("../base"); | ||
const typed_schema_strategy_1 = require("../typed-schema-strategy"); | ||
const lodash_1 = __importDefault(require("lodash")); | ||
class StringStrategy extends base_1.TypedSchemaStrategy { | ||
class StringStrategy extends typed_schema_strategy_1.TypedSchemaStrategy { | ||
constructor(schemaNode) { | ||
@@ -15,0 +15,0 @@ super(schemaNode); |
export declare class MaxLength { | ||
keywords: Set<string>; | ||
maxLength: number | null; | ||
addObject(string: string): void; | ||
addSchema(schema: Record<string, any>): void; | ||
addObject(string: string): void; | ||
toSchema(): { | ||
@@ -7,0 +7,0 @@ maxLength: number; |
@@ -13,2 +13,7 @@ "use strict"; | ||
} | ||
addObject(string) { | ||
this.maxLength = lodash_1.default.isNil(this.maxLength) | ||
? string.length | ||
: Math.max(this.maxLength, string.length); | ||
} | ||
addSchema(schema) { | ||
@@ -22,7 +27,2 @@ if (lodash_1.default.isNil(this.maxLength)) { | ||
} | ||
addObject(string) { | ||
this.maxLength = lodash_1.default.isNil(this.maxLength) | ||
? string.length | ||
: Math.max(this.maxLength, string.length); | ||
} | ||
toSchema() { | ||
@@ -29,0 +29,0 @@ return { maxLength: Math.round(this.maxLength) }; |
export declare class MinLength { | ||
keywords: Set<string>; | ||
minLength: number | null; | ||
addObject(string: string): void; | ||
addSchema(schema: Record<string, any>): void; | ||
addObject(string: string): void; | ||
toSchema(): { | ||
@@ -7,0 +7,0 @@ minLength: number; |
@@ -13,2 +13,7 @@ "use strict"; | ||
} | ||
addObject(string) { | ||
this.minLength = lodash_1.default.isNil(this.minLength) | ||
? string.length | ||
: Math.min(this.minLength, string.length); | ||
} | ||
addSchema(schema) { | ||
@@ -22,7 +27,2 @@ if (lodash_1.default.isNil(this.minLength)) { | ||
} | ||
addObject(string) { | ||
this.minLength = lodash_1.default.isNil(this.minLength) | ||
? string.length | ||
: Math.min(this.minLength, string.length); | ||
} | ||
toSchema() { | ||
@@ -29,0 +29,0 @@ return { minLength: Math.round(this.minLength) }; |
{ | ||
"name": "schematized", | ||
"description": "Turn JS objects into JSON schemas that continue to improve as you provide examples.", | ||
"version": "1.4.0", | ||
"description": "Turn objects into JSON schemas! The more examples you provide, the better your schema will be.", | ||
"version": "1.5.0", | ||
"files": [ | ||
@@ -17,3 +17,3 @@ "dist/" | ||
"fix": "xo src --fix", | ||
"test": "yarn build && yarn ava --verbose", | ||
"test": "yarn build && yarn nyc ava --verbose", | ||
"clean": "rimraf ./dist" | ||
@@ -50,3 +50,4 @@ }, | ||
"include": [ | ||
"__tests__/*" | ||
"__tests__/*", | ||
"examples/*" | ||
], | ||
@@ -53,0 +54,0 @@ "exclude": [ |
156
README.md
@@ -5,13 +5,32 @@ # Schematized | ||
![Build-Test-Publish](https://github.com/ryparker/JSON-Schema-Builder/workflows/Build-Test-Publish/badge.svg) | ||
[![semantic-release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg)](https://github.com/semantic-release/semantic-release) | ||
![Build-Test-Publish](https://github.com/ryparker/JSON-Schema-Builder/workflows/Build-Test-Publish/badge.svg) | ||
[![XO code style](https://img.shields.io/badge/code_style-XO-5ed9c7.svg)](https://github.com/xojs/xo) | ||
Turn JS objects into JSON schemas that continue to improve as you provide examples. | ||
Turn objects into JSON schemas! The more examples you provide, the better your schema will be. | ||
A Node port of the Python module Genson. | ||
--- | ||
- [Schematized](#schematized) | ||
- [:rocket: Quickstart](#-quickstart) | ||
- [Schema from the single example](#schema-from-the-single-example) | ||
- [Schema from the two examples](#schema-from-the-two-examples) | ||
- [Schema from the two examples and the schema](#schema-from-the-two-examples-and-the-schema) | ||
- [📖 API](#-api) | ||
- [✅ Supported Schema Features](#-supported-schema-features) | ||
- [Types](#types) | ||
- [Typeless](#typeless) | ||
- [String](#string) | ||
- [Supported String formats](#supported-string-formats) | ||
- [Number](#number) | ||
- [Object](#object) | ||
- [Array](#array) | ||
--- | ||
## :rocket: Quickstart | ||
1. Add dependency | ||
1. **Add dependency** | ||
@@ -22,7 +41,7 @@ ```shell | ||
2. Basic usage | ||
2. **Basic usage** : [See output](#schema-from-the-single-example) | ||
```ts | ||
import { SchemaBuilder } from 'schematized' // Typescript & ES6+ | ||
const { default: SchemaBuilder } = require('schematized') // CommonJS | ||
const { SchemaBuilder } = require('schematized') // CommonJS | ||
@@ -38,6 +57,6 @@ const builder = new SchemaBuilder() | ||
// Produce JSON Schemas! | ||
const schema = builder.toSchema() | ||
const schema = builder.toPrettySchema() | ||
``` | ||
3. Improve the schema | ||
3. **Improve the schema with examples** : [See output](#schema-from-the-two-examples) | ||
@@ -47,3 +66,2 @@ ```ts | ||
// Add more example objects | ||
builder.addObject({ | ||
@@ -57,4 +75,9 @@ token: 'Bearer 6498d9afc96d1d8d881a2b7ded4f9290', | ||
}) | ||
``` | ||
// Or combine data from another JSON Schema | ||
4. **Improve the schema with existing schemas** : [See output](#schema-from-the-two-examples-and-the-schema) | ||
```ts | ||
... | ||
builder.addSchema({ | ||
@@ -66,4 +89,6 @@ title: '/user response', | ||
**Schema from the single example:** | ||
--- | ||
### Schema from the single example | ||
```JSON | ||
@@ -95,3 +120,3 @@ { | ||
**Schema from the two examples:** | ||
### Schema from the two examples | ||
@@ -124,3 +149,3 @@ ```JSON | ||
**Schema from the two examples and the schema**: | ||
### Schema from the two examples and the schema | ||
@@ -154,1 +179,108 @@ ```JSON | ||
``` | ||
--- | ||
## 📖 API | ||
| Method | Definition | Parameter | | ||
| --------------------- | ----------------------------------------------- | ----------------- | | ||
| `.addObject($object)` | Add an example to improve the generated schema. | Valid JSON object | | ||
| `.addSchema($schema)` | Add schemas to improve the generated schema. | Valid JSON Schema | | ||
| `.toSchema()` | Generate the schema. | None | | ||
| `.toPrettySchema()` | Generate the schema and pretty print. | None | | ||
## ✅ Supported Schema Features | ||
Visit the [official JSON Schema site](https://json-schema.org/understanding-json-schema/reference/index.html) for specification details. | ||
### Types | ||
| Type | Supported | | ||
| ------- | --------- | | ||
| String | Yes | | ||
| Number | Yes | | ||
| Integer | Never | | ||
| Object | Yes | | ||
| Array | Yes | | ||
| Tuple | Not yet | | ||
| Boolean | Yes | | ||
| Null | Yes | | ||
### Typeless | ||
| Constraint | addSchema() | addObject() | | ||
| ------------ | ----------- | ----------- | | ||
| title | Yes | Never | | ||
| description | Yes | Never | | ||
| \$comment | Yes | Never | | ||
| default | Not yet | Not yet | | ||
| examples | Not yet | Not yet | | ||
| enum | Not yet | Not yet | | ||
| const | Not yet | Not yet | | ||
| anyOf | Yes | Yes | | ||
| allOf | Not yet | Not yet | | ||
| oneOf | Not yet | Not yet | | ||
| not | Not yet | Not yet | | ||
| if/then/else | Not yet | Not yet | | ||
### String | ||
| Constraint | addSchema() | addObject() | | ||
| ---------------- | ----------- | ----------- | | ||
| maxLength | Yes | Yes | | ||
| minLength | Yes | Yes | | ||
| format | Yes | Yes | | ||
| pattern | Not yet | Not yet | | ||
| contentMediaType | Not yet | Not yet | | ||
| contentEncoding | Not yet | Not yet | | ||
#### Supported String formats | ||
| Format | Supported? | | ||
| --------------------- | ---------- | | ||
| date-time | Yes | | ||
| date | Yes | | ||
| time | Yes | | ||
| email | Yes | | ||
| hostname | Not yet | | ||
| idn-hostname | Not yet | | ||
| ipv4 | Yes | | ||
| ipv6 | Yes | | ||
| uri | Yes | | ||
| uri-reference | Not yet | | ||
| url | Yes | | ||
| uuid | Yes | | ||
| iri | Not yet | | ||
| iri-reference | Not yet | | ||
| uri-template | Not yet | | ||
| json-pointer | Not yet | | ||
| relative-json-pointer | Not yet | | ||
| regex | Not yet | | ||
### Number | ||
| Constraint | addSchema() | addObject() | | ||
| ---------------- | ----------- | ----------- | | ||
| maximum | Yes | Yes | | ||
| minimum | Yes | Yes | | ||
| exclusiveMaximum | Not yet | Not yet | | ||
| exclusiveMinimum | Not yet | Not yet | | ||
| multiple | Not yet | Not yet | | ||
### Object | ||
| Constraint | addSchema() | addObject() | | ||
| -------------------- | ----------- | ----------- | | ||
| propertyPatterns | Yes | Yes | | ||
| additionalProperties | Yes | Yes | | ||
| required | Yes | Yes | | ||
| maxProperties | Not yet | Not yet | | ||
| minProperties | Not yet | Not yet | | ||
### Array | ||
| Constraint | addSchema() | addObject() | | ||
| ----------- | ----------- | ----------- | | ||
| maxItems | Not yet | Not yet | | ||
| minItems | Not yet | Not yet | | ||
| uniqueItems | Not yet | Not yet | |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
68681
66
975
278