Skip to content

Commit caced07

Browse files
committed
Initial commit, supporting 2020 schema docs
1 parent de25ff5 commit caced07

14 files changed

+1851
-33
lines changed

.eslintignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
node_modules
2+
test-node.js
23
lib

README.md

Lines changed: 219 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,228 @@
1-
# Typescript Node Package Repository Template
1+
# json-schema-fns
22

3-
> Create a new repo from this template to get started creating a Typescript npm package
3+
> Modern utility library and typescript typings for building JSON Schema documents dynamically
44
55
<!-- ![Coverage lines](./badges/badge-lines.svg) -->
6-
<!-- ![Tests](https://github.com/jsonhero-io/ts-node-package-template/actions/workflows/test.yml/badge.svg?branch=main) -->
7-
<!-- [![Downloads](https://img.shields.io/npm/dm/%40jsonhero%2Fts-node-package-template.svg)](https://npmjs.com/@jsonhero/ts-node-package-template) -->
8-
<!-- [![Install size](https://packagephobia.com/badge?p=%40jsonhero%2Fts-node-package-template)](https://packagephobia.com/result?p=@jsonhero/ts-node-package-template) -->
6+
<!-- ![Tests](https://github.com/jsonhero-io/json-schema-fns/actions/workflows/test.yml/badge.svg?branch=main) -->
7+
<!-- [![Downloads](https://img.shields.io/npm/dm/%40jsonhero%2Fjson-schema-fns.svg)](https://npmjs.com/@jsonhero/json-schema-fns) -->
8+
<!-- [![Install size](https://packagephobia.com/badge?p=%40jsonhero%2Fjson-schema-fns)](https://packagephobia.com/result?p=@jsonhero/json-schema-fns) -->
99

1010
## Features
1111

12-
- Written in typescript
13-
- Github workflows for running tests and publishing package to NPM on Github release
14-
- Rollup for building commonjs and esm compatible npm package
15-
- ts-node and ts-jest integration
16-
- Generate coverage badges
17-
- ESLint with Typescript and prettier support
18-
- Pre-commit hooks to format code with prettier and run ESLint
12+
- Build JSON Schema documents for various drafts (currently only draft-2020-12 but more coming soon)
13+
- Strongly typed documents using Typescript
14+
- Allows you to build correct JSON Schema documents using dynamic data
1915

2016
## Usage
2117

22-
Create a new repository from this template on Github with the [following instructions](https://docs.github.com/en/repositories/creating-and-managing-repositories/creating-a-repository-from-a-template)
18+
Create a simple draft-2020-12 document:
19+
20+
```ts
21+
import { s } from "json-schema-fns";
22+
23+
const schema = s.object({
24+
properties: [s.requiredProperty("foo", s.string()), s.property("bar", s.int())],
25+
});
26+
27+
schema.toSchemaDocument();
28+
```
29+
30+
Will result in
31+
32+
```json
33+
{
34+
"$schema": "https://json-schema.org/draft/2020-12/schema#",
35+
"$id": "https://jsonhero.io/schemas/root.json",
36+
"type": "object",
37+
"properties": {
38+
"foo": { "type": "string" },
39+
"bar": { "type": "integer" }
40+
},
41+
"required": ["foo"]
42+
}
43+
```
44+
45+
You can also import the types for a specific draft to use, like so:
46+
47+
```typescript
48+
import { s, Schema, IntSchema, StringSchema, StringFormat } from "json-schema-fns";
49+
50+
function buildIntSchema(maximum: number, minimum: number): IntSchema {
51+
return s.int({ minimum, maximum });
52+
}
53+
54+
function buildStringFormat(format: JSONStriStringFormatgFormat): StringSchema {
55+
return s.string({ format });
56+
}
57+
```
58+
59+
`json-schema-fns` support all the features of JSON schema:
60+
61+
```typescript
62+
import { s } from "json-schema-fns";
63+
64+
const phoneNumber = s.def("phoneNumber", s.string({ pattern: "^[0-9]{3}-[0-9]{3}-[0-9]{4}$" }));
65+
const usAddress = s.def(
66+
"usAddress",
67+
s.object({
68+
properties: [s.requiredProperty("zipCode", s.string())],
69+
}),
70+
);
71+
72+
const ukAddress = s.def(
73+
"ukAddress",
74+
s.object({
75+
properties: [s.requiredProperty("postCode", s.string())],
76+
}),
77+
);
78+
79+
s.object({
80+
$id: "/schemas/person",
81+
title: "Person Profile",
82+
description: "Attributes of a person object",
83+
examples: [
84+
{
85+
name: "Eric",
86+
87+
},
88+
],
89+
$comment: "This is just a preview",
90+
default: {},
91+
properties: [
92+
s.requiredProperty("name", s.string()),
93+
s.property("email", s.string({ format: "email" })),
94+
s.property("phoneNumber", s.ref("phoneNumber")),
95+
s.property("billingAddress", s.oneOf(s.ref("ukAddress"), s.ref("usAddress"))),
96+
],
97+
patternProperties: [s.patternProperty("^[A-Za-z]$", s.string())],
98+
additionalProperties: s.array({
99+
items: s.number({ minimum: 0, maximum: 5000 }),
100+
}),
101+
propertyNames: "^[A-Za-z_][A-Za-z0-9_]*$",
102+
minProperties: 3,
103+
maxProperties: 20,
104+
unevaluatedProperties: false,
105+
defs: [phoneNumber, usAddress, ukAddress],
106+
}).toSchemaDocument();
107+
```
108+
109+
Will result in
110+
111+
```json
112+
{
113+
"$schema": "https://json-schema.org/draft/2020-12/schema",
114+
"type": "object",
115+
"$id": "/schemas/person",
116+
"title": "Person Profile",
117+
"description": "Attributes of a person object",
118+
"examples": [
119+
{
120+
"name": "Eric",
121+
"email": "[email protected]"
122+
}
123+
],
124+
"$comment": "This is just a preview",
125+
"default": {},
126+
"minProperties": 3,
127+
"maxProperties": 20,
128+
"unevaluatedProperties": false,
129+
"properties": {
130+
"name": {
131+
"type": "string"
132+
},
133+
"email": {
134+
"type": "string",
135+
"format": "email"
136+
},
137+
"phoneNumber": {
138+
"$ref": "#/$defs/phoneNumber"
139+
},
140+
"billingAddress": {
141+
"oneOf": [
142+
{
143+
"$ref": "#/$defs/ukAddress"
144+
},
145+
{
146+
"$ref": "#/$defs/usAddress"
147+
}
148+
]
149+
}
150+
},
151+
"required": ["name"],
152+
"patternProperties": {
153+
"^[A-Za-z]$": {
154+
"type": "string"
155+
}
156+
},
157+
"propertyNames": {
158+
"pattern": "^[A-Za-z_][A-Za-z0-9_]*$"
159+
},
160+
"additionalProperties": {
161+
"type": "array",
162+
"items": {
163+
"type": "number",
164+
"minimum": 0,
165+
"maximum": 5000
166+
}
167+
},
168+
"$defs": {
169+
"phoneNumber": {
170+
"type": "string",
171+
"pattern": "^[0-9]{3}-[0-9]{3}-[0-9]{4}$"
172+
},
173+
"usAddress": {
174+
"type": "object",
175+
"properties": {
176+
"zipCode": {
177+
"type": "string"
178+
}
179+
},
180+
"required": ["zipCode"]
181+
},
182+
"ukAddress": {
183+
"type": "object",
184+
"properties": {
185+
"postCode": {
186+
"type": "string"
187+
}
188+
},
189+
"required": ["postCode"]
190+
}
191+
}
192+
}
193+
```
194+
195+
# API
196+
197+
## `s`
198+
199+
All the builder methods for creating subschemas are available on the `s` object
200+
201+
```typescript
202+
import { s } from "json-schema-fns";
203+
```
204+
205+
Or if you want to import a specific dialect:
206+
207+
```typescript
208+
import { s } from "json-schema-fns/2020";
209+
```
210+
211+
### `object`
212+
213+
### `array`
214+
215+
### `string`
216+
217+
### `integer` and `number`
218+
219+
### `nil`
220+
221+
### `boolean`
222+
223+
## Roadmap
224+
225+
- Support draft-04
226+
- Support draft-06
227+
- Support draft-07
228+
- Support draft/2019-09

0 commit comments

Comments
 (0)