Skip to content

Commit

Permalink
feat: support json schema #30 (#31)
Browse files Browse the repository at this point in the history
* bump up minor

* add useJsonSchema param

* add example file

* add new module

* fix

* add isOption field

* add jsony library

* wip parser

* code format

* del: nim 1.0, 1.2

* fix test

* format code

* add disableOption param

* format code

* fix: headUper function move to utils.nim

* fix: format code

* fix: use headUpper

* fix: add newNilTypeObjectDefinition

* fix: format code

* fix

* fix: format code

* WIP: add testcode

* fix: format code

* wip

* fix: format code

* format code

* format code

* fix: support nested object

* fix: bump up major

* fix: typeToNimType

* format code

* fix: add JsonSchemaParser

* format code

* fix: add $ref validation

* format code

* feat: support $ref and $defs

* format code

* feat: support $ref primitive type

* format code

* feat: activate JSON Schema in CLI

* chore: delete unused import

* format code

* add: sample json schema file

* chore: write JSON Schema usage

* chore: fix section titles

* small fix

* fix sample code

* add api usage

* format code

* fix cli help message

* add doc comment

* change disableOption to disableOptionType

* add examle code

* fix help

* fix link
  • Loading branch information
jiro4989 authored Nov 2, 2022
1 parent 15c1d80 commit 8445e9a
Show file tree
Hide file tree
Showing 12 changed files with 718 additions and 32 deletions.
2 changes: 0 additions & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,6 @@ jobs:
os:
- ubuntu-latest
nim-version:
- '1.0.x'
- '1.2.x'
- '1.4.x'
- '1.6.x'
- 'stable'
Expand Down
109 changes: 99 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@ This was inspired by [gojson](https://github.com/ChimeraCoder/gojson).

* Nim (stable version)

## Usage examples
## Usage examples (CLI)

`nimjson` writes `NilType` type if a value or a first value of an array is null.
Please fix `NilType` type yourself.

### Large JSON example
### Large JSON

```bash
% curl -s https://api.github.com/repos/jiro4989/nimjson | nimjson -O:Repository
Expand Down Expand Up @@ -131,7 +131,7 @@ type
node_id: string
```

### Simple JSON example
### Simple JSON

```bash
% nimjson examples/primitive.json
Expand Down Expand Up @@ -172,14 +172,82 @@ type
height: int64
```

### API usage
### JSON Schema

```nim
import std/json
`nimjson` supports partially [JSON Schema](https://json-schema.org/understanding-json-schema/index.html).
`nimjson` generates Nim type definition with JSON Schema when you enable `-j` option.

```bash
$ nimjson -j examples/json_schema.json
type
Object = ref object
`type`: string
id: string
timestamp: string
stream: string
consumer: string
consumer_seq: string
stream_seq: string
deliveries: int64
domain: Option[string]
```

It is wrapped by default in the `Option` type that properties not included in the `required` parameter of JSON Schema.
If you don't want to use `Option` type, you can use `--disable-option-type` option.

```bash
$ nimjson -j --disable-option-type examples/json_schema.json
type
Object = ref object
`type`: string
id: string
timestamp: string
stream: string
consumer: string
consumer_seq: string
stream_seq: string
deliveries: int64
domain: string
```

`nimjson` supports `$ref` and `$defs` keywords.
But it doesn't support URL of `$ref`.

This is supported:

```json
{
"$id": "https://example.com/product.schema.json",
"type": "object",
"properties": {
"product": { "$ref": "#/$defs/product" },
"product2": { "$ref": "#/$defs/product2" }
},
"$defs": {
"product": { "type": "string" },
"product2": { "type": "array", "items": { "type": "string" } }
}
}
```

This is NOT supported:

```json
{
"$id": "https://example.com/product.schema.json",
"type": "object",
"properties": {
"product": { "$ref": "https://example.com/schemas/address" }
}
}
```

## Usage examples (API)

```nim
import nimjson
echo """{"keyStr":"str", "keyInt":1}""".parseJson().toTypeString()
echo """{"keyStr":"str", "keyInt":1}""".toTypeString()
# Output:
# type
Expand All @@ -188,7 +256,7 @@ echo """{"keyStr":"str", "keyInt":1}""".parseJson().toTypeString()
# keyStr: string
# keyInt: int64
echo "examples/primitive.json".parseFile().toTypeString("testObject")
echo "examples/primitive.json".readFile().toTypeString("testObject")
# Output:
# type
Expand All @@ -201,6 +269,25 @@ echo "examples/primitive.json".parseFile().toTypeString("testObject")
# nullField: NilType
```

JSON Schema:

```nim
import nimjson
echo "examples/json_schema.json".readFile().toTypeString("testObject", jsonSchema = true)
type
TestObject = ref object
`type`: string
id: string
timestamp: string
stream: string
consumer: string
consumer_seq: string
stream_seq: string
deliveries: int64
domain: Option[string]
```

## Installation

### Nim users
Expand All @@ -212,14 +299,14 @@ nimble install nimjson
### Linux users (Debian base distros)

```bash
wget https://github.com/jiro4989/nimjson/releases/download/v2.0.0/nimjson_2.0.0_amd64.deb
wget https://github.com/jiro4989/nimjson/releases/download/v3.0.0/nimjson_3.0.0_amd64.deb
sudo dpkg -i ./nimjson*.deb
```

### Linux users (RHEL compatible distros)

```bash
yum install https://github.com/jiro4989/nimjson/releases/download/v2.0.0/nimjson-2.0.0-1.el7.x86_64.rpm
yum install https://github.com/jiro4989/nimjson/releases/download/v3.0.0/nimjson-3.0.0-1.el7.x86_64.rpm
```

## Help
Expand All @@ -241,6 +328,8 @@ yum install https://github.com/jiro4989/nimjson/releases/download/v2.0.0/nimjson
-O, --object-name:OBJECT_NAME Set object type name
-p, --public-field Public fields
-q, --quote-field Quotes all fields
-j, --json-schema Read JSON as JSON Schema format
--disable-option-type (Only JSON Schema) Disable using Option type

## License

Expand Down
60 changes: 60 additions & 0 deletions examples/json_schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://nats.io/schemas/jetstream/advisory/v1/nak.json",
"description": "Advisory published when a message was naked using a AckNak acknowledgement",
"title": "io.nats.jetstream.advisory.v1.nak",
"type": "object",
"required": [
"type",
"id",
"timestamp",
"stream",
"consumer",
"consumer_seq",
"stream_seq",
"deliveries"
],
"additionalProperties": false,
"properties": {
"type": {
"type": "string",
"const": "io.nats.jetstream.advisory.v1.nak"
},
"id": {
"type": "string",
"description": "Unique correlation ID for this event"
},
"timestamp": {
"type": "string",
"description": "The time this event was created in RFC3339 format"
},
"stream": {
"type": "string",
"description": "The name of the stream where the message is stored"
},
"consumer": {
"type": "string",
"description": "The name of the consumer where the message was naked"
},
"consumer_seq": {
"type": "string",
"minimum": 1,
"description": "The sequence of the message in the consumer that was naked"
},
"stream_seq": {
"type": "string",
"minimum": 1,
"description": "The sequence of the message in the stream that was naked"
},
"deliveries": {
"type": "integer",
"minimum": 1,
"description": "The number of deliveries that were attempted"
},
"domain": {
"type": "string",
"minimum": 1,
"description": "The domain of the JetStreamServer"
}
}
}
12 changes: 12 additions & 0 deletions examples/json_schema_2.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"$id": "https://example.com/product.schema.json",
"type": "object",
"properties": {
"product": { "$ref": "#/$defs/product" },
"product2": { "$ref": "#/$defs/product2" }
},
"$defs": {
"product": { "type": "string" },
"product2": { "type": "array", "items": { "type": "string" } }
}
}
7 changes: 4 additions & 3 deletions examples/readfile/main.nim
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import nimjson
import json

echo """{"keyStr":"str", "keyInt":1}""".parseJson().toTypeString()
echo "../primitive.json".parseFile().toTypeString("testObject")
echo """{"keyStr":"str", "keyInt":1}""".toTypeString()
echo "../primitive.json".readFile().toTypeString("testObject")
echo "../json_schema.json".readFile().toTypeString("testObject",
jsonSchema = true)
5 changes: 3 additions & 2 deletions nimjson.nimble
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Package

version = "2.0.1"
version = "3.0.0"
author = "jiro4989"
description = "nimjson generates nim object definitions from json documents."
license = "MIT"
Expand All @@ -11,7 +11,8 @@ installExt = @["nim"]

# Dependencies

requires "nim >= 0.20.0"
requires "nim >= 1.4.0"
requires "jsony == 1.1.3"

import std/strformat
import std/os
Expand Down
Loading

0 comments on commit 8445e9a

Please sign in to comment.