Giter Club home page Giter Club logo

generate's Introduction

generate

Generates Go (golang) Structs and Validation code from JSON schema.

Requirements

  • Go 1.8+

Usage

Install

$ go get -u github.com/a-h/generate/...

or

Build

$ make

Run

$ schema-generate exampleschema.json

Example

This schema

{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "title": "Example",
  "id": "http://example.com/exampleschema.json",
  "type": "object",
  "description": "An example JSON Schema",
  "properties": {
    "name": {
      "type": "string"
    },
    "address": {
      "$ref": "#/definitions/address"
    },
    "status": {
      "$ref": "#/definitions/status"
    }
  },
  "definitions": {
    "address": {
      "id": "address",
      "type": "object",
      "description": "Address",
      "properties": {
        "street": {
          "type": "string",
          "description": "Address 1",
          "maxLength": 40
        },
        "houseNumber": {
          "type": "integer",
          "description": "House Number"
        }
      }
    },
    "status": {
      "type": "object",
      "properties": {
        "favouritecat": {
          "enum": [
            "A",
            "B",
            "C"
          ],
          "type": "string",
          "description": "The favourite cat.",
          "maxLength": 1
        }
      }
    }
  }
}

generates

package main

type Address struct {
  HouseNumber int `json:"houseNumber,omitempty"`
  Street string `json:"street,omitempty"`
}

type Example struct {
  Address *Address `json:"address,omitempty"`
  Name string `json:"name,omitempty"`
  Status *Status `json:"status,omitempty"`
}

type Status struct {
  Favouritecat string `json:"favouritecat,omitempty"`
}

See the test/ directory for more examples.

generate's People

Contributors

a-h avatar andy-miracl avatar antoineco avatar gidsi avatar ieure avatar merlincox avatar mwlazlo avatar nicovogelaar avatar sqs avatar yvesf avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

generate's Issues

AnyOf throws error when used with $refs

The attached Schema produces the error

Failure generating structs: missing types for Name with errors failed to get the type for Name with error failed to get a primitive type for schemaType and subtype , missing types for Name with errors failed to get the type for Name with error failed to get a primitive type for schemaType and subtype

mytest.txt

Stack overflow on big schema file

When feeding schema-generate with a big schema file, it may abort with stack overflow.

Steps to reproduce:

  1. Download this schema file of Shopware Customer. It is ~266 KB big.
  2. The file is missing $schema and $id, I added the following bit (don't know if the schema is correct).
  3. Feed the augmented file to schema-generate and wait.
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://stoplight.io/api/v1/projects/shopware/admin-api/nodes/adminapi.json/components/schemas/Customer"

Result

The program aborts: overflow.log. schema-generate was built with go version go1.17.6 windows/amd64.

Expected Result

schema-generate does not crash, though it might exit with another error because I don't know if the example schema file is valid.

Required fields are flagged with `omitempty`

If you compile this schema:

{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "name": "Repository Configuration",
    "type": "object",
    "additionalProperties": false,
    "required": [ "name" ],
    "properties": {
        "name": {
            "type": "string",
            "description": "Repository name."
        },
        "repositories": {
            "type": ["object", "array"],
            "description": "A set of additional repositories where packages can be found.",
            "additionalProperties": true
        }
    }
}

you will get

package main

type Root struct {
  Name string `json:"name,omitempty"`
  Repositories * `json:"repositories,omitempty"`
}

But the Name field is flagged as required and flagged as omitempty.
Shouldn`t it be

package main

type Root struct {
  Name string `json:"name"`
  Repositories * `json:"repositories,omitempty"`
}

Regression in 485ac9 regarding generated variable names

Commit 485ac91f55d29aa83ba86515ca7a6b2bff940503 generates the following code:

Input:

{
    "$schema": "http://json-schema.org/draft-07/schema#",
    "$id": "ssl_certificate.jschema",
    "title": "sslcertificate",
    "type": "object",
    "additionalProperties": false,
    "properties": {
        "code": {
            "type": "string",
            "pattern": "^[a-z0-9]{3,10}$"
        },
        "key-url": {
            "description": "The URL to the certificate key.",
            "type": "string"
        },
        "crt-url": {
            "description": "The URL to the certificate data.",
            "type": "string"
        },
        "cacrt-url": {
            "description": "The URL to the ca certificate data.",
            "type": "string"
        }
    },
    "required": [
        "code",
        "key-url",
        "crt-url"
    ]
}

Output:

func (strct *Sslcertificate) UnmarshalJSON(b []byte) error {
    codeReceived := false
    crt-urlReceived := false
    key-urlReceived := false
    var jsonMap map[string]json.RawMessage
    if err := json.Unmarshal(b, &jsonMap); err != nil {
        return err
    }
    ...

The previous commit f3043e0 does not have this issue.

Maybe a merge issue?

Generate time.Time from string/date-time

Would it be possible to generate a Go time.Time type from schema string/date-time? Example:

    "start_date": {
      "description": "The actual start date",
      "type": "string",
      "format": "date-time"
    }

currently creates

StartDate string `json:"start_date"`

but in our case we would prefer

StartDate time.Time `json:"start_date"`

Invalid go code: "-" in struct names

If you compile this:

{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "name": "Repository Configuration",
    "type": "object",
    "additionalProperties": false,
    "required": [ "name" ],
    "properties": {
        "name": {
            "type": "string",
            "description": "Repository name."
        },
        "include-filename": {
            "type": "string",
            "description": "Specify filename instead of default include/all${SHA1_HASH}.json"
        }
    }
}

you will get this as a result:

package main

type Root struct {
  Include-filename string `json:"include-filename,omitempty"`
  Name string `json:"name,omitempty"`
}

As you see the var Include-filename includes a - which leads to invalid go code

Allow for Array of Object support

Hi,

Thanks for solving issue #4.

While looking at my schemas, I encountered another issue.
If I use arrays of objects (which I do), they are not properly referenced and only one of them is actually created (under the name Root and referenced as []object).

See schema below :

{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "id": "physical_server.json",
  "description": "Physical Server asset",
  "type": "object",
  "properties": {
    "id": {
      "description": "BSON ID",
      "type": "string"
    },
    "notes": {
      "type": "string"
    },
    "type": {
      "type": "string",
      "description": "Type of asset this represents",
      "pattern": "^physical_server$"
    },
    "created": {
      "type": "string"
    },
    "updated": {
      "type": "string"
    },
    "deleted": {
      "type": "string"
    },
    "attributes": {
      "type": "object",
      "description": "Specific attributes of the asset",
      "properties": {
        "hostname": {
          "type": "string"
        },
        "environments": {
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "operating_system": {
          "type": "object",
          "description": "Running operating system",
          "properties": {
            "family": {
              "type": "string"
            },
            "name": {
              "type": "string"
            },
            "version": {
              "type": "string"
            },
            "revision": {
              "type": "string"
            }
          }
        },
        "disk": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "brand":{"type":"string"},
              "size":{"type":"number"},
              "type":{"type":"string"}
            }
          }
        },
        "location": {
          "type": "string",
          "description": "Physical location of this server (datacenter, rack, pod, etc)"
        },
        "serial_number": {
          "type": "string"
        }
      }
    },
    "links": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "asset_id": {
            "type": "string"
          },
          "relationship": {
            "type": "string"
          },
          "description": {
            "type": "string"
          }
        }
      }
    },
    "tags": {
      "type": "array",
      "items": {
        "type": "string"
      }
    }
  }
}

Here is the output I get :

package main

type Attributes struct {
  Disk []object `json:"disk,omitempty"`
  Environments []string `json:"environments,omitempty"`
  Hostname string `json:"hostname,omitempty"`
  Location string `json:"location,omitempty"`
  Operatingsystem *Operatingsystem `json:"operating_system,omitempty"`
  Serialnumber string `json:"serial_number,omitempty"`
}

type Operatingsystem struct {
  Family string `json:"family,omitempty"`
  Name string `json:"name,omitempty"`
  Revision string `json:"revision,omitempty"`
  Version string `json:"version,omitempty"`
}

type Physicalserver.json struct {
  Attributes *Attributes `json:"attributes,omitempty"`
  Created string `json:"created,omitempty"`
  Deleted string `json:"deleted,omitempty"`
  Id string `json:"id,omitempty"`
  Links []object `json:"links,omitempty"`
  Notes string `json:"notes,omitempty"`
  Tags []string `json:"tags,omitempty"`
  Type string `json:"type,omitempty"`
  Updated string `json:"updated,omitempty"`
}

type Root struct {
  Brand string `json:"brand,omitempty"`
  Size float64 `json:"size,omitempty"`
  Type string `json:"type,omitempty"`
}

Handling $refs which are HTTP URLs

Hi!

First, I am super glad you have written this library, it already does most of what I need to do, namely programatically generate structs from schema definitions like these:

https://redfish.dmtf.org/schemas/ComputerSystem.v1_5_0.json

As you can see, the a lot of the $refs are specified with URLs pointing to other locations. I can see that in generator.go:getTypeForField() you are parsing the string as a URL. What do you think about checking the url.Scheme field and making an HTTP request to resolve it?

I need to find a way to process all the redfish schemata so if you are interested on working on this with me let me know.

feature: convert `description` to comment?

Our schemas use description and examples to provide info about the properties. Would be great if these can be converted to comments in the structs to developers can see these notes in their IDE.

patternProperties is not supported

It seems that whenever my JSONSchema makes use of the patternProperties constructor, the resulting struct is empty.

        optionalCategoriesList: {
          type: 'object',
          patternProperties: {
            '^[0-9]+$': { type: 'string' },
          },
          additionalProperties: false,
        },

Output:

// OptionalCategoriesList 
type OptionalCategoriesList struct {
}

Converting mkvmerge schema to Go silently generates incorrect code?

I've been trying to convert the mkvmerge v14 JSON Schema to a Go Struct. The program generates the output file without complaints, but certain fields appear to be missing.

One example: The source contains the default_track field inside properties, but this is not anywhere in the generated Go source.

I have impression that this could be happening due to multiple fields called properties in the source, but haven't dug into the source code to have a more educated opinion.

Values in "examples" (section 10.4) can be of any type

As written here:

The value of this keyword MUST be an array. There are no restrictions placed on the values within the array. [...]

However, the schema struct defines:

	Examples []string

In consequence it fails if there is a number in the examples array. The error message then looks like this:

the JSON type 'number' cannot be converted into the Go 'string' type on struct 'Schema', field 'Examples'. See input file xxxxxx.json line 553, character 1

I believe this is fixed by just changing []string to []interface{}. Since the Examples field seems to be unused in the generator the will be no conflict.

Custom `MarshalJSON()` ignores `omitempty`

I have a schema with a UUID property. It has a regexp to validate its contents, but isn't marked as required:

"uuid": {
    "type": "string",
    "pattern": "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$"
}

Non-required fields get an omitempty added to their json struct tag:

	Uud string `json:"uuid,omitempty"`

However, MarshalJSON doesn't understand omitempty, so it always emits the field:

{"uuid": ""}

This causes schema validation to fail, since the empty string doesn't match the declared pattern.

Nested structs are not created

I'm new to go so I apologise for the lack of details here, but I'm trying to convert https://csrc.nist.gov/schema/nvd/feed/1.1/nvd_cve_feed_json_1.1.schema to go structs. It references https://csrc.nist.gov/schema/nvd/feed/1.1/CVE_JSON_4.0_min_1.1.schema.
I've downloaded both and I'm running using ~/go/bin/schema-generate ~/Downloads/CVE_JSON_4.0_min_1.1.schema.json ~/Downloads/nvd_cve_feed_json_1.1.schema.json.
The output file cannot be compiled, and fails with ./structs.go:52:11: undefined: DefImpact.

def_impact references another remote schema which I haven't included, so I think it's failing to report that it's missing another schema?

Issue when schema key having . (dot) in it

when schema contains a key with dot in it
a field in UnmarshalJSON function creating with dot (.) in it and getting code errors

like template.hardwareIdReceived := false in below snippet

func (strct *Attrs) UnmarshalJSON(b []byte) error {
    template.hardwareIdReceived := false
    var jsonMap map[string]json.RawMessage
    if err := json.Unmarshal(b, &jsonMap); err != nil {
        return err
    }
    // parse all the defined properties
    for k, v := range jsonMap {
        switch k {
        case "template.hardwareId":
            if err := json.Unmarshal([]byte(v), &strct.TemplateHardwareId); err != nil {
                return err
             }
            template.hardwareIdReceived = true
        }
    }
    // check if template.hardwareId (a required property) was received
    if !template.hardwareIdReceived {
        return errors.New("\"template.hardwareId\" is required but was not present")
    }
    return nil
}

is there any way to avoid it ?

Compiler errors, is Go 1.7.5 too old?

Or is the cmd sub-package not intended to be built?

[17:49 me ~/.../github.com/metaleap]$ go get github.com/a-h/generate
[17:58 me ~/.../github.com/metaleap]$ go get github.com/a-h/generate/jsonschema
[18:01 me ~/.../github.com/metaleap]$ go get github.com/a-h/generate/cmd/schema-generate
# github.com/a-h/generate/cmd/schema-generate
../a-h/generate/cmd/schema-generate/main.go:46: jsonError.Struct undefined (type *json.UnmarshalTypeError has no field or method Struct)
../a-h/generate/cmd/schema-generate/main.go:46: jsonError.Field undefined (type *json.UnmarshalTypeError has no field or method Field)

additionalProperties

I have a schema that allows for additionalProperties of a given type. I think that each entry in the additionalProperties list should translate to a map[string]*MyType member in the struct. If there are multiple allowed types there should be a similar struct member for each one. (Im not sure how you would name each datamember though)?

Would you accept a PR for this feature?

Yaml ?

Hello,

Might be a stupid question ... but why no supporting yaml ? The yaml format is more suitable to handle configuration with comments than json. The json is more suitable for data exchange ...

structs with the same name

It looks like object types defined with the same name in different parts of the schema do not appear as distinct structs in the rendered golang code. e.g.

{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "x": {
      "type": "object",
      "properties": {
        "text": {
          "type": "string"
        }
      }
    },
    "y": {
      "type": "object",
      "properties": {
        "x": {
          "type": "object",
          "properties": {
            "number": {
              "type": "integer"
            }
          }
        }
      }
    },
    "z": {
      "type": "object",
      "properties": {
        "x" : {
          "type": "array",
          "items" : {
          "type": "object",
            "properties": {
              "float": {
                "type": "float"
              }
            }
          }      
        }
      }
    }
  }
}

Renders as

package main

type Root struct {
  X *X `json:"x,omitempty"`
  Y *Y `json:"y,omitempty"`
  Z *Z `json:"z,omitempty"`
}

type X struct {
  Float undefined `json:"float,omitempty"`
}

type Y struct {
  X *X `json:"x,omitempty"`
}

type Z struct {
  X []X `json:"x,omitempty"`
}

Not enough information in error messages

When I try to convert some complex structure, I got messages like:
Failed to parse the input JSON schema with error json: cannot unmarshal string into Go value of type jsonschema.Schema

There is no any information about a string in schema, where is a problem.

json: cannot unmarshal array into Go value of type string

If you try to compile this example:

{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "name": "Repository Configuration",
    "type": "object",
    "additionalProperties": false,
    "required": [ "name" ],
    "properties": {
        "name": {
            "type": "string",
            "description": "Repository name."
        },
        "repositories": {
            "type": ["object", "array"],
            "description": "A set of additional repositories where packages can be found.",
            "additionalProperties": true
        }
    }
}

via

$ go run main.go -i min.json
Failed to parse the input JSON schema with error  json: cannot unmarshal array into Go value of type string

If you change "type": ["object", "array"] to "type": "object", it works and produces

package main

type Root struct {
  Name string `json:"name,omitempty"`
  Repositories * `json:"repositories,omitempty"`
}

To be honest: This is tricky.
I don`t know how to react or solve this one. Maybe you got an idea and we can discuss it?

Case when type is nullable

Could this multi-type

"type": [
  "string",
  "null"
],

be interpreted as *string?

same would go for

"oneOf": [
  {
    "type": "null"
  },
  {
    "$ref": "#/definitions/NameType"
  }
]

Invalid generated Go code when parsing vega-lite json schema

Generating go code from:
https://vega.github.io/schema/vega-lite/v2.0.json
generates go with an invalid syntax. There are at least the following issues:

  1. some descriptions include the character \n and html. Multi-line comments are being generated but are not protected with //
  2. some names in that JSON schema include special characters such as < and > which are invalid in structure name in Go
  3. some references are not found. Perhaps they could be replaced by interface{} such that the code always compiles

Fails to generate metaschemas

I thought I'd generate structs for the JSON Schema meta-schema (the schema for a schema expressed in JSON Schema), so I could build my schema and let Go's type system enforce its validity.

The core schema fails with an error:

Failure generating structs:  processReference: reference "meta/core#/$defs/anchorString" not found at "#/properties/$recursiveAnchor"

The hyper schema doesn't error, but produces unusable output. This is the complete generated code:

// Code generated by schema-generate. DO NOT EDIT.

package main

// JSONHyperSchema
type JSONHyperSchema interface{}

Array support

Hi,

I have been unable to use arrays. See example here : http://json-schema.org/example1.html

{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "title": "Product set",
    "type": "array",
    "items": {
        "title": "Product",
        "type": "object",
        "properties": {
            "id": {
                "description": "The unique identifier for a product",
                "type": "number"
            },
            "name": {
                "type": "string"
            },
            "price": {
                "type": "number",
                "minimum": 0,
                "exclusiveMinimum": true
            },
            "tags": {
                "type": "array",
                "items": {
                    "type": "string"
                },
                "minItems": 1,
                "uniqueItems": true
            },
            "dimensions": {
                "type": "object",
                "properties": {
                    "length": {"type": "number"},
                    "width": {"type": "number"},
                    "height": {"type": "number"}
                },
                "required": ["length", "width", "height"]
            },
            "warehouseLocation": {
                "description": "Coordinates of the warehouse with the product",
                "$ref": "http://json-schema.org/geo"
            }
        },
        "required": ["id", "name", "price"]
    }
}

Here is the result :
go run main.go -i test.json
package main

Arrays of objects not supported in references

Parking this here until I (or somebody else) look into it.

Given the following JSON schema:

{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "title": "House",
    "type": "object",
    "definitions": {
        "address": {
            "type": "object",
            "properties": {
                "number": { "type": "integer" },
                "postcode": { "type": "string" }
            }
        },
        "owners": {
            "type": "array",
            "items": {
                "type": "object",
                "title": "person",
                "properties": {
                    "name": { "type": "string" }
                }
            }
        }
    },
    "properties": {
        "address": { "$ref": "#/definitions/address" },
        "owners": { "$ref": "#/definitions/owners" }
    }
}

The generated Owners field is not an array.

Moving definitions directly under properties almost* yields the expected result.

* minus the pointer symbol

Result:

// ...

// House 
type House struct {
  Address *Address `json:"address,omitempty"`
  Owners *Person `json:"owners,omitempty"`  // WRONG
                                            // should be []*Person
}

// ...

Expected:

// ...

// House 
type House struct {
  Address *Address `json:"address,omitempty"`
  Owners []*Person `json:"owners,omitempty"`
}

// ...

suggestion for use the code

I advise that readme.txt should have more detail. such as

  1. go mod init github.com/a-h/generate
  2. go mod tidy
  3. go run cmd/schema-generate/main.go your_test_json_path.json
  4. make
  5. ./schema-generate your_test_json_path.json

schemas aren't gofmt compliant

A totally reasonable super great two spaces for indentation are used in autogenerated code, so we have to run our code through gofmt before we check in our radically generated schemas.

This is a feature request to make the code congruent with gofmt output. I'll be happy to sent a PR or listen to a "this a dumb idea, don't do it" response.

Top-level objects do not support additionalProperties

Issue description

additionalProperties is only supported for nested schemas.

example
{
    "$schema": "http://json-schema.org/draft-07/schema#",
    "$id": "http://example.com/parameters.jschema",
    "title": "parameters",
    "type": "object",
    "properties": {
        "field": {
            "type": "object",
	    "additionalProperties": { "type": "string" }
        }
    }
}

generates

package main

// Parameters 
type Parameters struct {
    Field map[string]string `json:"field,omitempty"`
}

I would expect top-level schemas to also support additionalProperties.

example
{
    "$schema": "http://json-schema.org/draft-07/schema#",
    "$id": "http://example.com/parameters.jschema",
    "title": "parameters",
    "type": "object",
    "additionalProperties": { "type": "string" }
}

generates

package main
                   /*                          expected */
// Root            /*    // Field                       */
type Root string   /*    type Field map[string]string   */

License?

Your code looks promising, and I would like to modify some parts of it. You however have no license attached to it. Is that intentional?

Missing go.mod

Could a go.mod be added so that go get can work?
Moreover could the tool be versioned and tagged so that go install works?

support patterns in json schema?

Nice work putting this together. How do you think it would best support patterns in json schema? There could be a ".Validate() error" method which that would run through the regexen supplied as patterns in schema.

panic: runtime error: invalid memory address or nil pointer dereference

I try to compile this schema:

{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "name": "Repository Configuration",
    "type": "object",
    "additionalProperties": false,
    "required": [ "name" ],
    "properties": {
        "name": {
            "type": "string",
            "description": "Repository name."
        },
        "repositories": {
            "type": "array",
            "description": "A set of additional repositories where packages can be found.",
            "additionalProperties": true
        }
    }
}

via

$ go run main.go -i satis/res/satis-schema.json

and i got:

panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x18 pc=0x6c98b]

goroutine 1 [running]:
panic(0xd2d00, 0xc420012090)
	/usr/local/Cellar/go/1.7.4_2/libexec/src/runtime/panic.go:500 +0x1a1
github.com/a-h/generate/jsonschema.addTypeAndChildrenToMap(0xc420012cb0, 0xc, 0xc420012710, 0xc, 0xc420096800, 0xc42000a720)
	/.../Development/Go/src/github.com/a-h/generate/jsonschema/jsonschema.go:53 +0x52b
github.com/a-h/generate/jsonschema.addTypeAndChildrenToMap(0xed171, 0x1, 0x0, 0x0, 0xc420096000, 0xc42000a720)
	/.../Development/Go/src/github.com/a-h/generate/jsonschema/jsonschema.go:84 +0x212
github.com/a-h/generate/jsonschema.(*Schema).ExtractTypes(0xc420096000, 0x0)
	/.../Development/Go/src/github.com/a-h/generate/jsonschema/jsonschema.go:42 +0x90
github.com/a-h/generate.(*Generator).CreateStructs(0xc420041e70, 0x2d9b, 0xc420096000, 0x0)
	/.../Development/Go/src/github.com/a-h/generate/generator.go:31 +0x99
main.main()
	/.../Development/Go/src/github.com/a-h/generate/cmd/schema-generate/main.go:40 +0x315
exit status 2

Invalid go code: Missing data types

If you compile this:

{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "name": "Repository Configuration",
    "type": "object",
    "additionalProperties": false,
    "required": [ "name" ],
    "properties": {
        "name": {
            "type": "string",
            "description": "Repository name."
        },
        "abandoned": {
            "type": "object",
            "description": "List of packages marked as abandoned for this repository, the mark can be boolean or a package name/URL pointing to a recommended alternative.",
            "additionalProperties": {
                "type": ["boolean", "string"],
                "description": "A valid Package name"
            }
        }
    }
}

you will get this as a result:

package main

type Root struct {
  Abandoned * `json:"abandoned,omitempty"`
  Name string `json:"name,omitempty"`
}

As you see the var Abandoned as a pointer reference, but the type is missing.

Support defaults via const and New() functions

based on the following JSONSchema I would like to propose the generation of a New() function.

{
  "definitions": {},
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$id": "http://example.com/root.json",
  "type": "object",
  "title": "The Root Schema",
  "required": [
    "type",
    "data"
  ],
  "properties": {
    "type": {
      "$id": "#/properties/type",
      "type": "string",
      "title": "Type",
      "default": "notify_event",
      "examples": [
        "notify_event"
      ],
      "pattern": "^(.*)$"
    },
    "data": {
      "$id": "#/properties/data",
      "type": "object",
      "title": "Data",
      "required": [
        "resourceId",
        "type",
        "title",
        "content"
      ],
      "properties": {
        "resourceId": {
          "$id": "#/properties/data/properties/resourceId",
          "type": "string",
          "title": "Resourceid",
          "default": "",
          "examples": [
            "1a2s3d4f"
          ],
          "pattern": "^(.*)$"
        },
        "type": {
          "$id": "#/properties/data/properties/type",
          "type": "string",
          "title": "Type",
          "default": "rule",
          "examples": [
            "rule"
          ],
          "pattern": "^(.*)$"
        },
        "title": {
          "$id": "#/properties/data/properties/title",
          "type": "string",
          "title": "Title",
          "default": "",
          "examples": [
            "rule violation"
          ],
          "pattern": "^(.*)$"
        },
        "content": {
          "$id": "#/properties/data/properties/content",
          "type": "string",
          "title": "Content",
          "default": "",
          "examples": [
            "some explaination about rule violation"
          ],
          "pattern": "^(.*)$"
        }
      }
    }
  }
}

Proposed Output:

package main

const (
	defaultType     string = "notify_event"
	defaultDataType string = "rule"
)

type schema struct {
	Data theData `json:"data"`
	Type string  `json:"type"`
}

type data struct {
	Content    string `json:"content"`
	Resourceid string `json:"resourceId"`
	Title      string `json:"title"`
	Type       string `json:"type"`
}

func NewSchema() *schema {
	return &schema{
		Data: data{
			Content:    "",
			Resourceid: "",
			Title:      "",
			Type:       defaultDataType,
		},
		Type: defaultType,
	}
}

func NewData() *data {
	return &data{
		Content:    "",
		Resourceid: "",
		Title:      "",
		Type:       defaultDataType,
	}
}

Package cmd/schema-generate is gitignored when vendoring

In my project github.com/a-h/generate/cmd/schema-generate is imported under vendor/ and built before using it in build task, but it had to be git-added with -f option.
It due to schema-generate in .gitignore matching cmd/schema-generate. It would be better to rewrite .gitignore as /schema-generate.

support for generating enum types

Given an input like

{
  "$schema" : "http://json-schema.org/draft-04/schema#",
  "title" : "myObject",
  "type" : "object",
  "additionalProperties" : false,
  "properties" : {
    "type" : {
      "type" : "string",
      "enum" : [ "x", "y", "z" ],
      "default" : "x"
    }
}

this would currently get generated like

type MyObject {
    Type string `json:"type"`
}

It'd be really handy to generate a type for the enum, such as:

type MyObjectType string

const (
    MyObjectType_X  MyObjectType = "x"
    MyObjectType_Y = "y"
    MyObjectType_Z = "z"
)

type MyObject {
    Type MyObjectType `json:"type"`
}

Where MyObjectType would have a MarshalJSON/UnmarshalJSON that validated that the value was a valid MyObjectType, and produce an error if it was not.

If there's concerns about backwards compatibility, some additional niceties might be to keep the Type field as a string, but add validation to MarshalJSON/UnmarshalJSON to ensure it's a valid value, and error if it was not.

This is something I can probably dedicate a little bit of time into imlpementing, but I'm not sure what approach would be best in the eyes of the maintainer, or if there are other options I hadn't considered that may be desirable.

Treat oneOf(a, null) as optional

Would it be possible to treat a oneOf of 2 types where one is null as optional? Example:

          "oneOf": [
            {
              "type": "integer",
              "format": "int32"
            },
            {
              "type": "null"
            }
          ]

currently generates an interface{} type in Go. IMO it would be preferable to generate a *int instead. I know this could be coded differently in JSON schema to generate the desired output, but unfortunately, the schema is not under our control.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.