Code Monkey home page Code Monkey logo

datatype-expansion's Introduction

RAML.org Website

This repository contains the source code for the raml.org website written in Jekyll

Requirements

Running locally

Pull the code locally:

$ git clone [email protected]:raml-org/raml-org.git

Enter directory:

$ cd raml-org

Install all dependencies:

$ bundle install

Build & run the site:

$ bundle exec jekyll serve

How to add projects to the projects page?

RAML.org includes a projects page that lists tools around RAML that either are community or commercial driven. If you think, your project should be in this list, please fork this repository, add it into the projects.yml file, and send us a PR. We will review and let you know if we will be able to list it.

Another way to make sure your project is linked to our projects page is through assigning topics to your Github project. Links to each topics are below the list of projects on the projects page. The following topics are available:

Topic Description
raml-design Includes projects that specifically support people with the design of RAML documents.
raml-document Includes projects that focus on the documentation of APIs using RAML documents.
raml-build Includes projects that focus on build client or server code based on RAML documents.
raml-parser Includes projects that parses/validates RAML documents.
raml-test Includes projects that support people testing APIs based on RAML documents.
raml-utilities Includes other projects that do not fall into the other topics like converters.

Topics need to be assigned and managed by the owner of a project. Additionally, we still recommend people to search on Github for more projects that might not have these topics assigned.

Contribution

RAML's website is in fact an open source project and your contribution is very much appreciated. Before you start, you should check for open issues or open a fresh issue to start a discussion around an idea that you'd like to see on our website or a bug. If you want to support us fixing issues, please follow the steps below:

  1. Fork the repository on Github and make your changes on the develop branch (or branch off of it).
  2. Run the website to see if you fixed the issue.
  3. Send a pull request (with the develop branch as the target).

We will review your PR, comment if necessary, and merge it into our staging branch stg.

You can contribute to the following:

  • spelling mistakes
  • new projects
  • blog posts
  • and others, after carefully reviewing the issue you created

datatype-expansion's People

Contributors

antoniogarrote avatar darkrodry avatar dependabot[bot] avatar forsakenharmony avatar greenkeeper[bot] avatar jarrodek avatar jstoiko avatar postatum avatar sichvoge avatar svc-scm avatar trevorr avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

datatype-expansion's Issues

pattern properties looses name

If I have property that matches a pattern:

#%RAML 1.0
title: My API With Types
types:
  Person:
    properties:
      name:
        required: true
        type: string
      age:
        required: false
        type: number
      /^note\d+$/: # restrict any properties whose keys start with "note"
                   # followed by a string of one or more digits
        type: string

The expanded form looses the pattern and it just gets converted to a property with the name: ""

Inheritance+union type of property gives an error

Trying to get canonical form of Cat type gives an error. Replacing type: integer | number with anything that doesn't have union or removing inheritance from AnimalWithAddress makes script succeed.

AnimalWithAddress:
  properties:
    address: string

Cat:
  type: AnimalWithAddress
  properties:
    age:
      type: integer | number
Error: No method in multimethod 'datatype-expansion.canonical-form/lt' for dispatch value: ["object" "union"]
    at Object.cljs$core$throw_no_method_error [as throw_no_method_error] (/home/post/projects/mulesoft/raml-parser-toolbelt/tools/datatype-expansion/examples/nodejs/node_modules/datatype-expansion/node/cljs/core.js:33311:8)
    at cljs.core.MultiFn.call.G__10851__3 (/home/post/projects/mulesoft/raml-parser-toolbelt/tools/datatype-expansion/examples/nodejs/node_modules/datatype-expansion/node/cljs/core.js:33369:11)
    at cljs.core.MultiFn.call.G__10851 [as call] (/home/post/projects/mulesoft/raml-parser-toolbelt/tools/datatype-expansion/examples/nodejs/node_modules/datatype-expansion/node/cljs/core.js:33628:20)
    at /home/post/projects/mulesoft/raml-parser-toolbelt/tools/datatype-expansion/examples/nodejs/node_modules/datatype-expansion/node/datatype_expansion/canonical_form.js:715:107
    at cljs.core.MultiFn.call.G__10851__2 (/home/post/projects/mulesoft/raml-parser-toolbelt/tools/datatype-expansion/examples/nodejs/node_modules/datatype-expansion/node/cljs/core.js:33359:106)
    at cljs.core.MultiFn.call.G__10851 [as call] (/home/post/projects/mulesoft/raml-parser-toolbelt/tools/datatype-expansion/examples/nodejs/node_modules/datatype-expansion/node/cljs/core.js:33626:20)
    at /home/post/projects/mulesoft/raml-parser-toolbelt/tools/datatype-expansion/examples/nodejs/node_modules/datatype-expansion/node/datatype_expansion/js.js:194:67
    at /home/post/projects/mulesoft/raml-parser-toolbelt/tools/datatype-expansion/examples/nodejs/node_modules/datatype-expansion/node/datatype_expansion/js.js:227:51
    at datatype_expansion.js.canonicalForm.cljs.core.async.impl.dispatch.run.call.datatype_expansion$js$canonicalForm_$_state_machine__17768__auto____1 (/home/post/projects/mulesoft/raml-parser-toolbelt/tools/datatype-expansion/examples/nodejs/node_modules/datatype-expansion/node/datatype_expansion/js.js:248:4)
    at datatype_expansion.js.canonicalForm.cljs.core.async.impl.dispatch.run.call.datatype_expansion$js$canonicalForm_$_state_machine__17768__auto__ (/home/post/projects/mulesoft/raml-parser-toolbelt/tools/datatype-expansion/examples/nodejs/node_modules/datatype-expansion/node/datatype_expansion/js.js:264:78)

datatype-expansion and what happens next

Dear community,

As we want to support you as much as possible, we also want to follow the true community nature and being able to accept contributions with you. We found that this is harder with the implementation that we currently have and decided to migrate the datatype-expansion into JavaScript/TypeScript.

We hope you see that as a chance to also contribute to that project. Additionally, we will be able to better support you with fixes as well.

Hence, in the next few weeks we will start the migration and also rename that repository to "datatype-expansion" which will include only that.

We will come back with an ETA asap.

With the migration, we will tackle the different issues that came up as well of course. Please let us know if there are any concerns from your side.

Still ['type'] vs 'type' inconsistencies.

This is what I reported in an earlier ticket:

"I am using datatype-expansion in raml2obj to deal with inherited types. It's all mostly working, except that when you expand a root type and then get the canonical form, all the types on the properties and stuff are now just a string instead of an array, wheres normally a type is always an array (['string'])."

This is sadly still happening.

Test one: array of Foo.

#%RAML 1.0
title: Test
description: Test of array support
version: v1
baseUri:
  value: https://exmaple.com/{version}
protocols: HTTPS
mediaType: application/json

types:
  Foo:
    properties:
      id: string
  Foos: Foo[]

/foos:
  get:
    responses:
      200:
        body: Foos

After parsing and datatype expansion, the type of the body is 'array'.

Test two: array of string, so no datatype expansion is happening.

#%RAML 1.0
title: API used to test broken features
version: v1
baseUri: http://api.samplehost.com/broken/{version}
mediaType: application/json
protocols: [HTTP, HTTPS]

/:
  get:
    responses:
      200:
        body:
          type: string[]
          example: ["somevalue","anothervalue"]

The type of body is ['array']. This is what I would indeed expect.

It's the datatype expansion which ends up creating a different type of type: string instead of array. This makes the overall output extremely hard to work with for tools like raml2obj and raml2html.

Can't make optional property having custom type

Getting canonical form if this type gives an error:

CatName:
  type: string

Cat:
  properties:
    name:
      type: CatName
      required: false
Error: Error in required property, making optional base class required property
    at datatype_expansion$utils$error (/home/post/projects/mulesoft/raml-parser-toolbelt/tools/datatype-expansion/examples/nodejs/node_modules/datatype-expansion/node/datatype_expansion/utils.js:43:8)
    at /home/post/projects/mulesoft/raml-parser-toolbelt/tools/datatype-expansion/examples/nodejs/node_modules/datatype-expansion/node/datatype_expansion/canonical_form.js:57:39
    at cljs.core.MultiFn.call.G__10851__4 (/home/post/projects/mulesoft/raml-parser-toolbelt/tools/datatype-expansion/examples/nodejs/node_modules/datatype-expansion/node/cljs/core.js:33385:110)
    at cljs.core.MultiFn.call.G__10851 [as call] (/home/post/projects/mulesoft/raml-parser-toolbelt/tools/datatype-expansion/examples/nodejs/node_modules/datatype-expansion/node/cljs/core.js:33630:20)
    at datatype_expansion$canonical_form$lt_restrictions (/home/post/projects/mulesoft/raml-parser-toolbelt/tools/datatype-expansion/examples/nodejs/node_modules/datatype-expansion/node/datatype_expansion/canonical_form.js:276:107)
    at /home/post/projects/mulesoft/raml-parser-toolbelt/tools/datatype-expansion/examples/nodejs/node_modules/datatype-expansion/node/datatype_expansion/canonical_form.js:489:120
    at cljs.core.MultiFn.call.G__10851__3 (/home/post/projects/mulesoft/raml-parser-toolbelt/tools/datatype-expansion/examples/nodejs/node_modules/datatype-expansion/node/cljs/core.js:33372:108)
    at cljs.core.MultiFn.call.G__10851 [as call] (/home/post/projects/mulesoft/raml-parser-toolbelt/tools/datatype-expansion/examples/nodejs/node_modules/datatype-expansion/node/cljs/core.js:33628:20)
    at /home/post/projects/mulesoft/raml-parser-toolbelt/tools/datatype-expansion/examples/nodejs/node_modules/datatype-expansion/node/datatype_expansion/canonical_form.js:742:107
    at cljs.core.MultiFn.call.G__10851__2 (/home/post/projects/mulesoft/raml-parser-toolbelt/tools/datatype-expansion/examples/nodejs/node_modules/datatype-expansion/node/cljs/core.js:33359:106)

Make union hoisting optional in canonicalization

Tools like raml2html use canonical form because it has some good properties, like type always being a string and inheritance being resolved. However, I don't think "Unions can only appear at the top level of the type form" is usually what is wanted for documentation. For instance, if I had an object type with 15 properties of the type string | number, I'd end up with a top-level union with 215 permutations. Do you think it would be reasonable to add an option to canonicalization that allows disabling hoisting of unions to the top level? If so, I can work on a pull request.

Default type 'string' isn't determined

As described here:

If, and only if, a type declaration contains neither a properties facet nor a type or schema facet, then the default type is string. 

Not sure if it should work or not, but it doesn't.
For type:

Cat:
  properties:
    city:

Getting canonical form outputs:

Error: Unknown type  in {:path ["Cat"], "CatWithCity" {:properties {:city "string"}}, :fixpoints #object [cljs.core.Atom {:val {}}], "Cat" {:properties {:city nil}}, "CatWithAddress" {:properties {:address "string"}}}
    at datatype_expansion$utils$error (/home/post/projects/mulesoft/raml-parser-toolbelt/tools/datatype-expansion/examples/nodejs/node_modules/datatype-expansion/node/datatype_expansion/utils.js:43:8)
    at datatype_expansion$expanded_form$expanded_form_inner (/home/post/projects/mulesoft/raml-parser-toolbelt/tools/datatype-expansion/examples/nodejs/node_modules/datatype-expansion/node/datatype_expansion/expanded_form.js:307:39)
    at /home/post/projects/mulesoft/raml-parser-toolbelt/tools/datatype-expansion/examples/nodejs/node_modules/datatype-expansion/node/datatype_expansion/expanded_form.js:168:74
    at /home/post/projects/mulesoft/raml-parser-toolbelt/tools/datatype-expansion/examples/nodejs/node_modules/datatype-expansion/node/cljs/core.js:16882:88
    at cljs.core.map.cljs$core$IFn$_invoke$arity$2 (/home/post/projects/mulesoft/raml-parser-toolbelt/tools/datatype-expansion/examples/nodejs/node_modules/datatype-expansion/node/cljs/core.js:16883:3)
    at cljs.core.LazySeq.sval (/home/post/projects/mulesoft/raml-parser-toolbelt/tools/datatype-expansion/examples/nodejs/node_modules/datatype-expansion/node/cljs/core.js:10909:109)
    at cljs.core.LazySeq.cljs$core$ISeqable$_seq$arity$1 (/home/post/projects/mulesoft/raml-parser-toolbelt/tools/datatype-expansion/examples/nodejs/node_modules/datatype-expansion/node/cljs/core.js:11060:10)
    at Object.cljs$core$seq [as seq] (/home/post/projects/mulesoft/raml-parser-toolbelt/tools/datatype-expansion/examples/nodejs/node_modules/datatype-expansion/node/cljs/core.js:4131:13)
    at Function.cljs.core.seq_reduce.cljs$core$IFn$_invoke$arity$3 (/home/post/projects/mulesoft/raml-parser-toolbelt/tools/datatype-expansion/examples/nodejs/node_modules/datatype-expansion/node/cljs/core.js:7634:26)
    at cljs.core.LazySeq.cljs$core$IReduce$_reduce$arity$3 (/home/post/projects/mulesoft/raml-parser-toolbelt/tools/datatype-expansion/examples/nodejs/node_modules/datatype-expansion/node/cljs/core.js:11030:29)

Issue with expansion of required properties

The following does not expand for some reason.

#%RAML 1.0
title: Person API

types:
  Address:
    type: object
    properties:
      street:
        type: string
  Person:
    type: object
    properties:
      home_address:
        type: Address
      work_address:
        type: Address
        required: false


/humans:
  post:
    body:
      application/json:
        type: Person

It trows the error: Error in required property, making optional base class required property

note: it works when removing the work_address property

Invalid Inheritance issue

When using the RAML below in Osprey and with the workaround from #50 I get following error:

Error: Invalid inheriance array -> [{:type "array", :items {:type "any"}}]
    at /workspace/osprey-raml1.0/node_modules/datatype-expansion/node/datatype_expansion/canonical_form.js:582:12
    at cljs.core.MultiFn.call.G__10851__3 (/workspace/osprey-raml1.0/node_modules/datatype-expansion/node/cljs/core.js:33372:108)
    at cljs.core.MultiFn.call.G__10851 [as call] (/workspace/osprey-raml1.0/node_modules/datatype-expansion/node/cljs/core.js:33628:20)
    at /workspace/osprey-raml1.0/node_modules/datatype-expansion/node/datatype_expansion/canonical_form.js:530:138
    at /workspace/osprey-raml1.0/node_modules/datatype-expansion/node/cljs/core.js:17998:135
    at /workspace/osprey-raml1.0/node_modules/datatype-expansion/node/cljs/core.js:7639:96
    at Function.cljs.core.seq_reduce.cljs$core$IFn$_invoke$arity$3 (/workspace/osprey-raml1.0/node_modules/datatype-expansion/node/cljs/core.js:7640:3)
    at Function.cljs.core.reduce.cljs$core$IFn$_invoke$arity$3 (/workspace/osprey-raml1.0/node_modules/datatype-expansion/node/cljs/core.js:7744:29)
    at Function.cljs.core.mapv.cljs$core$IFn$_invoke$arity$2 (/workspace/osprey-raml1.0/node_modules/datatype-expansion/node/cljs/core.js:17997:52)
    at cljs$core$mapv (/workspace/osprey-raml1.0/node_modules/datatype-expansion/node/cljs/core.js:17978:23)

Btw the error message should state Invalid inheritance ;)

#%RAML 1.0
title: Example API
types:
    PagedQueryResponse:
        type: object
        properties:
            count:
                type: integer
            total:
                type: integer
            offset:
                type: integer
            results:
                type: Resource[]
    ProductPagedQueryResponse:
        type: PagedQueryResponse
        properties:
            results:
                type: Product[]
    Resource:
        type: object
        properties:
            id:
                type: string
            version:
                type: integer
            createdAt:
                type: datetime
            lastModifiedAt:
                type: datetime
    Product:
        type: Resource
        properties:
            key?:
                type: string
/products:
  get:
    queryParameters:
      sort:
        enum: [username, name]
    responses:
      200:
        body:
          application/json:
            type: ProductPagedQueryResponse

When removing the results property from PagedQueryResponse the RAML works.

Canonicalization adds undefined required property to array of union

Take the following type:

  {
    type: 'array',
    items: {
      type: 'union',
      anyOf: ['string', 'number']
    }
  }

The expanded form is:

  {
    type: 'array',
    items: {
      type: 'union',
      anyOf: [{ type: 'string' }, { type: 'number' }]
    }
  }

The canonical form incorrectly includes a required property with the value undefined:

  {
    type: 'union',
    anyOf: [{
      type: 'array',
      items: {
        type: 'string'
      }
    }, {
      type: 'array',
      items: {
        type: 'number'
      }
    }],
    required: undefined
  }

Algorithm step 3.4 should propagate the required property to items only if specified in form (i.e. for cases where form is a property-value).

minType error incompatible types: [object, [object Object]]

The following type causes canonicalForm to fail with incompatible types: [object, [object Object]]:

  {
    type: {
      type: 'union',
      anyOf: [{
        type: {
          type: 'object'
        }
      }]
    },
    anyOf: [{
      type: 'object'
    }]
  }

The problem is that minType (which gets invoked due to canonicalization step 5, since the top-level type is an object) expects its arguments to be canonical, but the canonicalization algorithm only canonicalizes unions when they appear as property or array item types. Types that are themselves unions do not have their alternatives canonicalized (i.e. there is no canonicalization step for the type string union).

Note that the nesting of type objects above is not contrived; it arises naturally from inheritance:

  T1: {
    type: 'object'
  },
  T2: {
    type: 'T1'
  },
  T3: {
    type: 'union',
    anyOf: ['T2']
  },
  T4: {
    type: 'T3',
    anyOf: ['T1']
  }

(However, this inheritance example currently fails with incompatible types: [undefined, [object Object]] because expandedForm does not expand the T1 reference in T4. This is due to the undocumented expansion algorithm case typeof form.type === 'string' && form.type in bindings omitting if (form.anyOf !== undefined) form = expandUnion(form, bindings, context).)

Canonicalization can include properties in union

minType case 8 can include object-only properties like properties and additionalProperties in a union result. This confuses findClass in canonicalization, which will return object if properties is defined (even though type is union). I'll submit a PR with tests that demonstrate the issue.

datatype-expansion memory problems

Please see https://github.com/raml2html/raml2html/issues/326 for a description of the issue, but basically the expandedForm function has memory issues with certain RAML files.

Test file: api.raml.zip

#%RAML 1.0
title: some API
baseUri: https://someserver.com/api
mediaType: application/json

types:
  SomeProfile:
    type: object
    properties:
      attr1: string?
      attr2: string?
      attr3: string?
      attr4: string?
      attr5: string?
      attr6: string?
      attr7: string?
      attr8: string?
      attr9: string?
      attr10: string?
      attr11: string?
      attr12: string?
      attr13: string?
      attr14: string?
      attr15: string?

  ManyProfiles:
    type: object
    properties:
      profiles?: SomeProfile

/api:
  get:
    responses:
      200:
        body:
          type: ManyProfiles

Multiple inheritance + custom type bug

Note that getting canonical form if type Cat produces JSON with nested type.type for property name.

#%RAML 1.0 Library

types:
  CatName:
    type: string

  CatWithCity:
    type: object

  CatWithAddress:
    type: object

  Cat:
    type: [CatWithAddress, CatWithCity]
    properties:
      name:
        type: CatName
{
  "additionalProperties": true,
  "type": "object",
  "properties": {
    "name": {
      "type": {
        "type": "string"
      },
      "required": true
    }
  }
}

Cycling expansion issue

Using the RAML below in Osprey with a cycling usage of a type I get following error message:

Error: No method in multimethod 'datatype-expansion.canonical-form/canonical-form' for dispatch value: fixpoint
    at Object.cljs$core$throw_no_method_error [as throw_no_method_error] (/workspace/osprey-raml1.0/node_modules/datatype-expansion/node/cljs/core.js:33311:8)
    at cljs.core.MultiFn.call.G__10851__2 (/workspace/osprey-raml1.0/node_modules/datatype-expansion/node/cljs/core.js:33356:11)
    at cljs.core.MultiFn.call.G__10851 [as call] (/workspace/osprey-raml1.0/node_modules/datatype-expansion/node/cljs/core.js:33626:20)
    at /workspace/osprey-raml1.0/node_modules/datatype-expansion/node/datatype_expansion/canonical_form.js:790:112
    at /workspace/osprey-raml1.0/node_modules/datatype-expansion/node/cljs/core.js:19036:96
    at /workspace/osprey-raml1.0/node_modules/datatype-expansion/node/cljs/core.js:19037:3
    at cljs.core.PersistentVector.cljs$core$IReduce$_reduce$arity$3 (/workspace/osprey-raml1.0/node_modules/datatype-expansion/node/cljs/core.js:19052:3)
    at Function.cljs.core.reduce.cljs$core$IFn$_invoke$arity$3 (/workspace/osprey-raml1.0/node_modules/datatype-expansion/node/cljs/core.js:7733:13)
    at cljs$core$reduce (/workspace/osprey-raml1.0/node_modules/datatype-expansion/node/cljs/core.js:7701:25)
    at /workspace/osprey-raml1.0/node_modules/datatype-expansion/node/datatype_expansion/canonical_form.js:788:166
#%RAML 1.0
title: Example API
types:
    Category:
        type: object
        properties:
            name:
                type: string
            children?:
                type: Category[]
/{id}:
  get:
    queryParameters:
      sort:
        enum: [username, name]
    responses:
      200:
        body:
          application/json:
            type: Category

Using union in type's `type` gives weird output

Getting canonical form of Device gives following output with a bunch of nulls

Phone:
  type: object
  properties:
    manufacturer:
      type: string
    numberOfSIMCards:
      type: number
    kind: string
Notebook:
  type: object
  properties:
    manufacturer:
      type: string
    numberOfUSBPorts:
      type: number
    kind: string
Device:
  type: Phone | Notebook
{
  "discriminatorValue": null,
  "enum": null,
  "additionalProperties": null,
  "format": null,
  "multipleOf": null,
  "maxProperties": null,
  "uniqueItems": null,
  "anyOf": [
    {
      "properties": {
        "manufacturer": {
          "type": "string",
          "required": true
        },
        "numberOfSIMCards": {
          "type": "number",
          "required": true
        },
        "kind": {
          "type": "string",
          "required": true
        }
      },
      "additionalProperties": true,
      "type": "object"
    },
    {
      "properties": {
        "manufacturer": {
          "type": "string",
          "required": true
        },
        "numberOfUSBPorts": {
          "type": "number",
          "required": true
        },
        "kind": {
          "type": "string",
          "required": true
        }
      },
      "additionalProperties": true,
      "type": "object"
    }
  ],
  "default": null,
  "maximum": null,
  "type": "union",
  "minLength": null,
  "title": null,
  "minProperties": null,
  "examples": null,
  "fileTypes": null,
  "minimum": null,
  "minItems": null,
  "maxLength": null,
  "example": null,
  "xml": null,
  "required": null,
  "discriminator": null,
  "maxItems": null,
  "pattern": null
}

Error incompatible types

In new version I am receiving a lot of incompatible types: [object, [object Object]] errors when parsing the API: https://github.com/advanced-rest-client/raml-example-api

Stack:

Error: incompatible types: [object, [object Object]]
    at minType (/Users/pawelpsztyc/workspace/advanced-rest-client/raml2obj/node_modules/datatype-expansion/src/minType.js:302:9)
    at toCanonical (/Users/pawelpsztyc/workspace/advanced-rest-client/raml2obj/node_modules/datatype-expansion/src/canonical.js:162:36)
    at Object.canonicalForm (/Users/pawelpsztyc/workspace/advanced-rest-client/raml2obj/node_modules/datatype-expansion/src/canonical.js:19:12)

This is happening for the following types declared in the RAML:

  • AppPerson
  • Product
  • ExampleType.Org
  • ExampleType.AlertableAdmin

Previous version was expanding data types correctly.
I'm not sure what else I can add to help with debug.

No method in multimethod lt-restriction

Getting canonical form of type Cat gives me following error. Error repeats when replacing default with example, displayName, description and maybe some other props - I didn't test them all.

#%RAML 1.0 Library

types:
  Animal:
    default: Animal
    type: string

  Cat:
    type: Animal
    default: MyCat
Error: No method in multimethod 'datatype-expansion.canonical-form/lt-restriction' for dispatch value: :default
    at Object.cljs$core$throw_no_method_error [as throw_no_method_error] (/home/post/projects/mulesoft/raml-parser-toolbelt/tools/datatype-expansion/examples/nodejs/node_modules/datatype-expansion/node/cljs/core.js:33311:8)
    at cljs.core.MultiFn.call.G__10851__4 (/home/post/projects/mulesoft/raml-parser-toolbelt/tools/datatype-expansion/examples/nodejs/node_modules/datatype-expansion/node/cljs/core.js:33382:11)
    at cljs.core.MultiFn.call.G__10851 [as call] (/home/post/projects/mulesoft/raml-parser-toolbelt/tools/datatype-expansion/examples/nodejs/node_modules/datatype-expansion/node/cljs/core.js:33630:20)
    at datatype_expansion$canonical_form$lt_restrictions (/home/post/projects/mulesoft/raml-parser-toolbelt/tools/datatype-expansion/examples/nodejs/node_modules/datatype-expansion/node/datatype_expansion/canonical_form.js:276:107)
    at /home/post/projects/mulesoft/raml-parser-toolbelt/tools/datatype-expansion/examples/nodejs/node_modules/datatype-expansion/node/datatype_expansion/canonical_form.js:489:120
    at cljs.core.MultiFn.call.G__10851__3 (/home/post/projects/mulesoft/raml-parser-toolbelt/tools/datatype-expansion/examples/nodejs/node_modules/datatype-expansion/node/cljs/core.js:33372:108)
    at cljs.core.MultiFn.call.G__10851 [as call] (/home/post/projects/mulesoft/raml-parser-toolbelt/tools/datatype-expansion/examples/nodejs/node_modules/datatype-expansion/node/cljs/core.js:33628:20)
    at /home/post/projects/mulesoft/raml-parser-toolbelt/tools/datatype-expansion/examples/nodejs/node_modules/datatype-expansion/node/datatype_expansion/canonical_form.js:747:107
    at cljs.core.MultiFn.call.G__10851__2 (/home/post/projects/mulesoft/raml-parser-toolbelt/tools/datatype-expansion/examples/nodejs/node_modules/datatype-expansion/node/cljs/core.js:33359:106)
    at cljs.core.MultiFn.call.G__10851 [as call] (/home/post/projects/mulesoft/raml-parser-toolbelt/tools/datatype-expansion/examples/nodejs/node_modules/datatype-expansion/node/cljs/core.js:33626:20)

Extra attributes of properties are not preserved in minType

Take for instance the following type (as might be encountered from a RAML parse):

  {
    properties: {
      name: {
        type: ['string'],
        displayName: 'name'
      }
    }
  }

The expanded form is:

  {
    type: 'object',
    properties: {
      name: {
        type: [{
          type: 'string'
        }],
        required: true,
        displayName: 'name'
      }
    },
    additionalProperties: true
  }

The canonical form should be this:

  {
    type: 'object',
    properties: {
      name: {
        type: 'string',
        required: true,
        displayName: 'name'
      }
    },
    additionalProperties: true
  }

However, the displayName attribute is not included, because in the implementation of min-type 2.1, the sup type is arbitrarily chosen as the basis of the result, and non-restriction fields from sub are not copied to it. Other cases in min-type seem to arbitrarily chose sup or sub as the return basis, propagating extra fields from that object but not the other. I think the behavior for each case should be to propagate these fields.

Note that this only occurs when the property type is expressed as an array (which seems to be the current RAML parser behavior). I found this issue when trying to upgrade raml2obj to 0.2.2.

Goog is not defined with Jest.

Hi, I recently updated mocha tests to jest tests, and the jest can run without any problem, but the issue I'm having is the goog object from another module.

With mocha, it's not a problem to access this goog object, but for some reason when I run it with jest, it is undefined.

I believe this has something to do with how jest runs, so any pointer or help would be appreciated.

P.S when I run the same test with mocha, this isn't issue.

Here's the stack trace.

โ— Test suite failed to run

TypeError: goog.addDependency is not a function

  at Object.<anonymous> (node_modules/raml2obj/node_modules/datatype-expansion/node/cljs_deps.js:1:95)
  at Object.<anonymous> (node_modules/raml2obj/node_modules/datatype-expansion/index.js:20:1)
  at Object.<anonymous> (node_modules/raml2obj/index.js:6:15)
  at Object.<anonymous> (node_modules/raml2html/index.js:3:18)

Not sure if root properties next to 'allOf' make sense

This applied to anyOf/oneOf/allOf.
Having RAML type:

Cat:
  type: object
  maxProperties: 1
  properties:
    rating:
      type: string | integer

Canonical form will be:

{
  "additionalProperties": true,
  "maxProperties": 1,
  "type": "union",
  "anyOf": [
    {
      "properties": {
        "rating": {
          "type": "string",
          "required": true
        }
      },
      "additionalProperties": true,
      "maxProperties": 1,
      "type": "object"
    },
    {
      "properties": {
        "rating": {
          "type": "integer",
          "required": true
        }
      },
      "additionalProperties": true,
      "maxProperties": 1,
      "type": "object"
    }
  ]
}

As you can see, schemas in anyOf duplicate all params of root object like maxProperties.
Considering that using union adds multiple copies of that object to anyOf and to be valid instance has to be valid to any of them, does it make sense to keep root properties when anyOf is present?
As I imagine it maxProperties or additionalProperties will not be used in validation, because instance will be validated against schemas from anyOf.
I may be wrong here.

Canonicalized unions have extraneous additionalProperties

I think canonicalization algorithm 4.4.5.2 ("we remove the key properties") should be expanded to also include additionalProperties. Example:

  SimpleUnion: {
    properties: {
      a: 'string',
      b: 'number | string'
    }
  }

Expansion:

  SimpleUnion: {
    properties: {
      a: {
        type: 'string',
        required: true
      },
      b: {
        anyOf: [
          {
            type: 'number'
          },
          {
            type: 'string'
          }
        ],
        type: 'union',
        required: true
      }
    },
    additionalProperties: true,
    type: 'object'
  }

Canonicalization:

  SimpleUnion: {
    additionalProperties: true,
    type: 'union',
    anyOf: [
      {
        properties: {
          a: {
            type: 'string',
            required: true
          },
          b: {
            type: 'number',
            required: true
          }
        },
        additionalProperties: true,
        type: 'object'
      },
      {
        properties: {
          a: {
            type: 'string',
            required: true
          },
          b: {
            type: 'string',
            required: true
          }
        },
        additionalProperties: true,
        type: 'object'
      }
    ]
  }

In the canonicalization, the top-level additionalProperties seems like an unintended artifact of transforming the top-level object (into which expansion injected additionalProperties) into a union.

A way to to make it work in a browser

I've tried to use raml2object library in a browser (using browserify) but even if the project builds without errors I can't make it work because of Google JS Library and a way how it works in Node environment.
Detailed description can be found here: https://github.com/raml2html/raml2obj/issues/19

I'm wondering if there are plans to make the tools work in the browser so I could us it in a browser?

Using union in property type makes it required=true all the time

E.g. getting canonical form if this type gives following:

Cat:
  properties:
    name:
      type: string
      required: false

{
  "properties": {
    "name": {
      "type": "string",
      "required": false
    }
  },
  "additionalProperties": true,
  "type": "object",
  "required": true
}

But if we use union in type of name, it becomes required: true:

Cat:
  properties:
    name:
      type: string | string
      required: false

{
  "properties": {
    "name": {
      "type": "string",
      "required": true
    }
  },
  "additionalProperties": true,
  "type": "object",
  "required": true
}

PS. I know using union of strings doesn't make sense. I noticed this issue when using union of two array subtypes.

Using multiple inheritance in root gives much prettier output

This isn't the issues really, rather NOT using multiple inheritance in root gives a lot bigger and complicated output :)
This is just a thing to consider. Maybe there's something going on wrong in scripts.

E.g. if here is canonical form of type without multiple inheritance in root. As you can see, it places anyOf in root and adds multiple copies with a whole object just with a different values for age field type.

types:
  CatWithCity:
    properties:
      city: string
  Cat:
    type: CatWithCity
    properties:
      age: string | number
{
  "additionalProperties": true,
  "type": "union",
  "anyOf": [
    {
      "additionalProperties": true,
      "type": "object",
      "properties": {
        "age": {
          "type": "string",
          "required": true
        },
        "city": {
          "type": "string",
          "required": true
        }
      }
    },
    {
      "additionalProperties": true,
      "type": "object",
      "properties": {
        "age": {
          "type": "number",
          "required": true
        },
        "city": {
          "type": "string",
          "required": true
        }
      }
    }
  ]
}

Now if we add multiple inheritance, the output becomes much more pretty branching only where it's really needed and not in the root.

types:
  CatWithCity:
    properties:
      city: string

  CatWithAddress:
    properties:
      address: string

  Cat:
    type: [CatWithCity, CatWithAddress]
    properties:
      age: string | number
{
  "additionalProperties": true,
  "type": "object",
  "properties": {
    "address": {
      "type": "string",
      "required": true
    },
    "city": {
      "type": "string",
      "required": true
    },
    "age": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "number"
        }
      ],
      "type": "union",
      "required": true
    }
  }
}

2 datatype-expansion problems

I am using datatype-expansion in raml2obj to deal with inherited types. It's all mostly working, except that when you expand a root type and then get the canonical form, all the types on the properties and stuff are now just a string instead of an array, wheres normally a type is always an array (['string']). This makes the types inconsistent and I had to deal with that in raml2obj because in raml2html I don't want to deal with things that are something arrays but something strings. Doing the work in raml2obj to make them consistent works, but seems like the wrong place to fix this :)

There is a much more serious problem though: array types.

So in the world-music-api example, there is an AnotherEntry type, which in turn has the Event type. The Event type is of type array.

Now when I use the datatype-expansion library, I would expect that AnotherEntry is expanded into 'array', but instead it's expanded into ['Entry'] and nothing is copied over (expanded). This blocks the Entry properties from being shown on anything that uses AnotherEntry, because the expansion isn't final.

Hope that makes sense.

Properties ending with "?" aren't made optional anymore

Getting canonical form type with property ending with "?" doesn't make it required: false anymore. Iif I recall correctly it used to work before recent updates.

Cat:
  type: object
  properties:
    name?:
      type: string
{
  "properties": {
    "name?": {
      "type": "string",
      "required": true
    }
  },
  "additionalProperties": true,
  "type": "object",
  "required": true
}

Type of a `body` object is sometimes not processed by the library.

Source RAML: https://github.com/raml-org/raml-examples/blob/master/others/alainn-mobile-shopping/api.raml

This is very rare but I've noticed that in this case the type is not handled properly.

For the POST /mobile-tokens/{mobileType} which is defined as:

/mobile-tokens/{mobileType}:
  uriParameters:
    mobileType:
      type: string
      enum: [ios, android]
  post:
    body:
      type:
        properties:
          token: string
        example:
          token: afdasfas23lkesf

the output object is:

{
body: [
  {
    "name": "application/json",
    "displayName": "application/json",
    "required": true,
    "type": {
      "name": "type",
      "displayName": "type",
      "type": "object",
      "required": true,
      "properties": [
        {
          "name": "token",
          "displayName": "token",
          "type": "string",
          "required": true,
          "key": "token"
        }
      ],
      "examples": [
        "{\n  \"token\": \"afdasfas23lkesf\"\n}"
      ]
    },
    "key": "application/json"
  }
]
}

The problem is that the type property should equals object and the type properties should have been promoted to parent object.

Inherited subtypes not handled properly

Consider the following types:

{
  "Person": {
    "type": "object",
    "properties": {
      "name": "Name"
    }
  },
  "Employee": {
    "type": "Person",
    "properties": {
      "id": "string",
      "spouse": "Person"
    }
  },
  "Name": {
    "type": "string"
  }
}

Employee's expanded form outputs:

{
  "type": {
    "type": "object",
    "properties": {
      "name": {
        "type": "string",
        "required": true
      }
    },
    "additionalProperties": true
  },
  "properties": {
    "id": {
      "type": "string",
      "required": true
    },
    "spouse": {
      "type": "$recur",
      "required": true
    }
  },
  "additionalProperties": true
}

it should expand sub-types such as Spouse (including sub-sub-type Name) and output:

{
  "type": {
    "type": "object",
    "properties": {
      "name": {
        "type": "string",
        "required": true
      }
    },
    "additionalProperties": true
  },
  "properties": {
    "id": {
      "type": "string",
      "required": true
    },
    "spouse": {
      "type": "object",
      "properties": {
        "name": {
          "type": "string",
          "required": true
        }
      },
      "additionalProperties": true,
      "required": true
    }
  },
  "additionalProperties": true
}

Should canonicalization remove single-element type arrays?

The RAML parser always seems to return types as an array, even when there is no multiple inheritance. For instance:

  Account:
    properties:
      name: string

yields:

{ name: 'Account',
  displayName: 'Account',
  typePropertyKind: 'TYPE_EXPRESSION',
  type: [ 'object' ],
  properties:
   { name:
      { name: 'name',
        displayName: 'name',
        typePropertyKind: 'TYPE_EXPRESSION',
        type: [ 'string' ],
        required: true },

Type expansion will then expand type: [ 'string' ] to type: [ { type: 'string' } ]. Canonicalization will remove inheritance, so that type: [ 'object' ] just becomes type: 'object', but the property type expansion remains. However, when an inherited property is canonicalized, it is ultimately flatten (via min-type) to string form (e.g. type: 'string'). This causes property types to have more than one form after canonicalization, which seems to be, well, non-canonical.

Therefore, should a canonicalization rule be added to convert single-element (property) type arrays into the equivalent non-array form? For instance, if property p has a type of [t], where t is a single element, then a) if t is a string, then type simply becomes t, else b) t is an object and p is replaced with Object.assign({}, t, p2), where p2 is a clone of p that excludes type. This ensures that property attributes (such as example) take precedence over type attributes. Alternatively, if b) is undesirable because it potentially loses information, a) could still be done because it is the common case.

Presumably, this would be require a semver breaking change and/or a feature flag.

Subtype required=true doesn't override supertype required=false

Subtype property with required=true doesn't override supertype's property with required=false. Isn't required=true more strict than required=false?

Suggestion: here replace (and super sub) with (or super sub).

Type to test and output of canonical script:

Person:
  properties:
    name:
      type: string
      required: true
  type:
    type: object
    properties:
      name:
        type: string
        required: false
{
  "additionalProperties": true,
  "type": "object",
  "required": true,
  "properties": {
    "name": {
      "type": "string",
      "required": false
    }
  }
}

datatype-expansion shouldn't attempt to expand in-line types

For some reason, if I try to expand in-line types, it alters the JSON input slightly resulting in an error in canonicalForm().

var data = {
  "name": "obj",
  "displayName": "obj",
  "type": [
    "object"
  ],
  "required": true,
  "properties": {
    "existing_property": {
      "type": "string",
      "displayName": "existing_property",
      "name": "existing_property",
      "required": true
    }
  },
  "additionalProperties": false
}

var context = {
  "Sort": {
    "name": "Sort",
    "displayName": "Sort",
    "type": [
      "string"
    ],
    "required": true,
    "enum": [
      "desc",
      "asc"
    ]
  },
  "types-lib.User": {
    "name": "User",
    "displayName": "User",
    "type": [
      "object"
    ],
    "required": true,
    "properties": {
      "firstname": {
        "type": "string",
        "displayName": "firstname",
        "name": "firstname",
        "required": true
      },
      "lastname": {
        "type": "string",
        "displayName": "lastname",
        "name": "lastname",
        "required": true
      },
      "age": {
        "type": "number",
        "displayName": "age",
        "name": "age",
        "required": true
      }
    }
  }
}

var expanded = dtexp.expandedForm(data, context)

console.log(JSON.stringify(expanded, null, 2))
// {
//  "properties": {
//    "existing_property": {
//      "displayName": "existing_property",
//      "type": "string",
//      "required": true
//    }
//  },
//  "additionalProperties": false,
//  "displayName": "obj",
//  "name": "obj",
//  "type": [
//    {
//      "additionalProperties": true,
//      "type": "object"
//    }
//  ],
//  "required": true
// }
//
// ^-- expanded !== data for some reason

console.log(dtexp.canonicalForm(expanded))
// Error: sub type has a weaker constraint for additional-properties than base type

I think this may be the part of 'expanded' that causes the error:

  "type": [
    {
      "additionalProperties": true,
      "type": "object"
    }
  ]

description, displayName, facets are lost on property

When getting canonical form of RAML type, description, displayName, facets and defined facet value of property are lost.

Cat:
  type: object
  properties:
    name:
      description: Cat name
      displayName: Cat
      type: string
      facets:
        amazing: boolean
      amazing: true
{
  "properties": {
    "name": {
      "type": "string",
      "required": true
    }
  },
  "additionalProperties": true,
  "type": "object"
}

Inherited properties masked by miscellaneous attributes of type in canonical form

Take for instance the following types:

  Named: {
    properties: {
      name: 'string'
    }
  },
  InheritNamedWithNameAttribute: {
    name: 'InheritNamedWithNameAttribute',
    type: 'Named',
    properties: {
      other: 'string'
    }
  }

The expanded form is:

  Named: {
    type: 'object',
    properties: {
      name: {
        type: 'string',
        required: true
      }
    },
    additionalProperties: true
  },
  InheritNamedWithNameViaArray: {
    name: 'InheritNamedWithNameViaArray',
    type: {
      type: 'object',
      properties: {
        name: {
          type: 'string',
          required: true
        }
      },
      additionalProperties: true
    },
    properties: {
      other: {
        type: 'string',
        required: true
      }
    },
    additionalProperties: true
  }

The canonical form should be this:

  Named: {
    type: 'object',
    properties: {
      name: {
        type: 'string',
        required: true
      }
    },
    additionalProperties: true
  },
  InheritNamedWithNameViaArray: {
    name: 'InheritNamedWithNameViaArray',
    type: 'object',
    properties: {
      name: {
        type: 'string',
        required: true
      },
      other: {
        type: 'string',
        required: true
      }
    },
    additionalProperties: true
  }

However, the name property is excluded from InheritNamedWithNameAttribute, because in the implementation of min-type 6.3, the non-common property names are incorrectly searched for in the sub-type object's own properties, not in its properties value. I suppose it's up to interpretation whether min-type 6.3 is implying that properties should be used:

for each pair property-name property-value only in either super or sub we add it to the record common-props

I found this issue when trying to upgrade raml2obj to 0.2.2.

object and array types not supported in type array form

If object or array appear in an array of types (i.e. multiple inheritance form), expandedForm throws could not resolve: object or could not resolve: array, respectively. Although this form may not be of much practical value, recent versions of the RAML JS parser seem to always provide a type array.

Also, if array is used without items (which I believe is permissible by the spec), expandedForm throws form can only be a string or an object (because it is called recursively with undefined) and canonicalForm throws Cannot read property 'type' of undefined.

Example original types:

  ObjectInTypeArray: {
    type: ['object']
  },
  ArrayInTypeArray: {
    type: ['array']
  },

Expected expanded types:

  ObjectInTypeArray: {
    type: [{ type: 'object' }]
  },
  ArrayInTypeArray: {
    type: [{ type: 'array' }]
  },

Expected canonical types:

  ObjectInTypeArray: {
    properties: {},
    type: 'object'
  },
  ArrayInTypeArray: {
    items: { type: 'any' },
    type: 'array'
  },

'xml' node is lost on inheritance

I'm talking about this thing https://github.com/raml-org/raml-spec/blob/master/versions/raml-10/raml-10.md/#xml-serialization-of-type-instances

When supertype defines xml node, subtype doesn't have it when getting canonical form.
If defined directly on subtype it stays.

Getting canonical form of Cat gives:

Animal:
  type: string
  maxLength: 42
  xml:
    attribute: false
    wrapped: true
    name: cat
    prefix: animal
Cat:
  type: Animal
{
  "type": "string",
  "maxLength": 42,
  "required": true
}

The `schema` property is not expanded

Consider following API (https://github.com/raml-org/raml-examples/blob/master/others/world-music-api/api.raml):

types:
  Entry: |
    {
      "type": "array",
      "items": {
        "$ref": "#/definitions/song"
      },
      "definitions": {
        "song": {
          "type": "object",
          "properties": {
            "title": {
              "type": "string"
            },
            "artist": {
              "type": "string"
            }
          }
        }
      }
    }
resourceTypes:
  collection:
    get:
      description: returns a list of <<resourcePathName|!singularize>>
      responses:
        200:
          body:
            application/json:
              schema: <<resourcePathName|!singularize|!uppercamelcase>>
/entry:
  type:  collection

The GET /entry's response is resolved to the following object:

[
  {
    "code": "200",
    "body": [
      {
        "name": "application/json",
        "displayName": "application/json",
        "schema": [
          "Entry"
        ],
        "required": true,
        "key": "application/json"
      }
    ],
    "key": "200"
  },
  ...
]

The Entry schema is not applied to the object.

Unions in a type array are not canonicalized correctly

If a union type appears in an array of types (i.e. multiple inheritance form), canonicalForm returns an empty anyOf array. The array form is not intentional or desired, but recent versions of the RAML JS parser seem to always wrap types in an array.

Example original type:

{ type: ['number | string'] }

Expanded type:

{
  type: [{
    anyOf: [
      { type: 'number' },
      { type: 'string' }
    ],
    type: 'union'
  }]
}

Expected canonical type:

{
  anyOf: [
    { type: 'number' },
    { type: 'string' }
  ],
  type: 'union'
}

Actual canonical type:

{
  anyOf: [],
  type: 'union'
}

I'm looking into a fix. This seems to be a case not anticipated in algorithms.md.

Getting canonical form of multiple inheritance gives an error

When trying to get canonical form of type with multiple inheritance, script breaks with error.
Types (trying to get canonical form of "Cat"):

Animal:
  properties:
    age: integer
Pet:
  properties:
    owner: string
Cat:
  type: [Animal, Pet]

Error:

Error: No method in multimethod 'datatype-expansion.canonical-form/lt' for dispatch value: [{:properties {:age {:type "integer", :required true}}, :additionalProperties true, :type "object", :required true} "object"]
    at Object.cljs$core$throw_no_method_error [as throw_no_method_error] (/home/post/projects/mulesoft/raml-parser-toolbelt/tools/datatype-expansion/examples/nodejs/node_modules/datatype-expansion/node/cljs/core.js:33311:8)
    at cljs.core.MultiFn.call.G__10851__3 (/home/post/projects/mulesoft/raml-parser-toolbelt/tools/datatype-expansion/examples/nodejs/node_modules/datatype-expansion/node/cljs/core.js:33369:11)
    at cljs.core.MultiFn.call.G__10851 [as call] (/home/post/projects/mulesoft/raml-parser-toolbelt/tools/datatype-expansion/examples/nodejs/node_modules/datatype-expansion/node/cljs/core.js:33628:20)
    at /home/post/projects/mulesoft/raml-parser-toolbelt/tools/datatype-expansion/examples/nodejs/node_modules/datatype-expansion/node/datatype_expansion/canonical_form.js:738:45
    at /home/post/projects/mulesoft/raml-parser-toolbelt/tools/datatype-expansion/examples/nodejs/node_modules/datatype-expansion/node/cljs/core.js:19036:96
    at /home/post/projects/mulesoft/raml-parser-toolbelt/tools/datatype-expansion/examples/nodejs/node_modules/datatype-expansion/node/cljs/core.js:19037:3
    at cljs.core.PersistentVector.cljs$core$IReduce$_reduce$arity$3 (/home/post/projects/mulesoft/raml-parser-toolbelt/tools/datatype-expansion/examples/nodejs/node_modules/datatype-expansion/node/cljs/core.js:19052:3)
    at Function.cljs.core.reduce.cljs$core$IFn$_invoke$arity$3 (/home/post/projects/mulesoft/raml-parser-toolbelt/tools/datatype-expansion/examples/nodejs/node_modules/datatype-expansion/node/cljs/core.js:7733:13)
    at cljs$core$reduce (/home/post/projects/mulesoft/raml-parser-toolbelt/tools/datatype-expansion/examples/nodejs/node_modules/datatype-expansion/node/cljs/core.js:7701:25)
    at /home/post/projects/mulesoft/raml-parser-toolbelt/tools/datatype-expansion/examples/nodejs/node_modules/datatype-expansion/node/datatype_expansion/canonical_form.js:736:87

canonicalForm reorders properties

canonicalForm, as called from raml2html, via raml2obj (_expandRootTypes) returns a json structure with the properties in a different order. This is not generally a big issue, since most fields are fetched by their respective key.
However, in some cases such as for "properties", the order is important as the documentation should reflect the order the attributes were defined in the RAML file.

Expanded script loses restrictions of optional properties

Below are a type and result of converting it to expanded form. As you can see, minLength restriction is lost.

Person:
  properties:
    bio:
      type: string?
      minLength: 1
{
  "properties": {
    "bio": {
      "type": "union",
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "nil"
        }
      ]
    }
  },
  "additionalProperties": true,
  "type": "object",
  "required": true
}

Doesn't work with RAML parser

Current version seems to not work with the RAML parser.

Here's an example RAML:

#%RAML 1.0
title: Test
description: Test of array support
version: v1
baseUri: https://exmaple.com/{version}
protocols: HTTPS
mediaType: application/json

types:
  Foo:
    properties:
      id: string
  Foos: Foo[]

/foos:
  get:
    responses:
      200:
        body: Foos

Extraction JSON data from yaml file:

const raml = require('raml-1-parser');
raml.loadApi(source, {
    rejectOnErrors: false
})
.then(result => {
    return result.expand(true).toJSON({serializeMetadata: false});
});

This produces an array for types:

[
  {
    "Foo": {
      "name": "Foo",
      "displayName": "Foo",
      "typePropertyKind": "TYPE_EXPRESSION",
      "type": [
        "object"
      ],
      "properties": {
        "id": {
          "name": "id",
          "displayName": "id",
          "typePropertyKind": "TYPE_EXPRESSION",
          "type": [
            "string"
          ],
          "required": true
        }
      }
    }
  },
  {
    "Foos": {
      "name": "Foos",
      "displayName": "Foos",
      "typePropertyKind": "TYPE_EXPRESSION",
      "type": [
        "array"
      ],
      "items": "Foo"
    }
  }
]

Event after transforming the array into an object like this:

{
  "Foo": {
    "name": "Foo",
    "displayName": "Foo",
    "typePropertyKind": "TYPE_EXPRESSION",
    "type": [
      "object"
    ],
    "properties": {
      "id": {
        "name": "id",
        "displayName": "id",
        "typePropertyKind": "TYPE_EXPRESSION",
        "type": [
          "string"
        ],
        "required": true
      }
    }
  },
  "Foos": {
    "name": "Foos",
    "displayName": "Foos",
    "typePropertyKind": "TYPE_EXPRESSION",
    "type": [
      "array"
    ],
    "items": "Foo"
  }
}

the library produces following output:

{
  "Foo": {
    "type": "object",
    "properties": {
      "id": {
        "name": "id",
        "displayName": "id",
        "typePropertyKind": "TYPE_EXPRESSION",
        "type": [
          {
            "type": "string"
          }
        ],
        "required": true
      }
    },
    "name": "Foo",
    "displayName": "Foo",
    "typePropertyKind": "TYPE_EXPRESSION",
    "additionalProperties": true
  },
  "Foos": {
    "type": "array",
    "items": {
      "0": "F",
      "1": "o",
      "2": "o"
    },
    "name": "Foos",
    "displayName": "Foos",
    "typePropertyKind": "TYPE_EXPRESSION"
  }
}

Expected result is Foos to be expanded correctly.

TypeError Exception in canonical_form

Using Ospray with this RAML I get following error:

TypeError: datatype_expansion.canonical_form.Exception is not a constructor
    at /workspace/osprey-raml1.0/node_modules/datatype-expansion/node/datatype_expansion/canonical_form.js:582:12
    at cljs.core.MultiFn.call.G__10851__3 (/workspace/osprey-raml1.0/node_modules/datatype-expansion/node/cljs/core.js:33372:108)
    at cljs.core.MultiFn.call.G__10851 [as call] (/workspace/osprey-raml1.0/node_modules/datatype-expansion/node/cljs/core.js:33628:20)
    at /workspace/osprey-raml1.0/node_modules/datatype-expansion/node/datatype_expansion/canonical_form.js:530:138
    at /workspace/osprey-raml1.0/node_modules/datatype-expansion/node/cljs/core.js:17998:135
    at /workspace/osprey-raml1.0/node_modules/datatype-expansion/node/cljs/core.js:7639:96
    at Function.cljs.core.seq_reduce.cljs$core$IFn$_invoke$arity$3 (/workspace/osprey-raml1.0/node_modules/datatype-expansion/node/cljs/core.js:7640:3)
    at Function.cljs.core.reduce.cljs$core$IFn$_invoke$arity$3 (/workspace/osprey-raml1.0/node_modules/datatype-expansion/node/cljs/core.js:7744:29)
    at Function.cljs.core.mapv.cljs$core$IFn$_invoke$arity$2 (/workspace/osprey-raml1.0/node_modules/datatype-expansion/node/cljs/core.js:17997:52)
    at cljs$core$mapv (/workspace/osprey-raml1.0/node_modules/datatype-expansion/node/cljs/core.js:17978:23)

When changing it to Error instead of Exception at least I get the underlying issues reported

Array 'items' gets required=true assigned

Not sure if it makes sense. Relative to what items are required?
PS. Canonical form

Cat:
  properties:
    pawsNames:
      type: array
      items: string
{
  "properties": {
    "pawsNames": {
      "type": "array",
      "items": {
        "type": "string",
        "required": true
      },
      "required": true
    }
  },
  "additionalProperties": true,
  "type": "object",
  "required": true
}

Canonical form of type 'file' is missing 'fileTypes'

fileTypes is missing is canonical form of following type.

Cat:
  properties:
    photo:
      type: file
      fileTypes: ['image/jpeg', 'image/png']
      minLength: 1
      maxLength: 307200
{
  "properties": {
    "photo": {
      "type": "file",
      "minLength": 1,
      "maxLength": 307200,
      "required": true
    }
  },
  "additionalProperties": true,
  "type": "object",
  "required": true
}

It is also missing when type subclasses type "file":

Cat:
  type: file
  fileTypes: ['image/jpeg', 'image/png']
  minLength: 1
  maxLength: 307200
{
  "type": "file",
  "minLength": 1,
  "maxLength": 307200,
  "required": true
}

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.