{"id":27230822,"url":"https://github.com/vodori/schema-forms","last_synced_at":"2025-04-10T13:33:39.265Z","repository":{"id":57729498,"uuid":"177368534","full_name":"vodori/schema-forms","owner":"vodori","description":"Convert prismatic schemas into JSON schemas compatible with react-jsonschema-form","archived":false,"fork":false,"pushed_at":"2020-02-13T00:20:13.000Z","size":47,"stargazers_count":12,"open_issues_count":1,"forks_count":0,"subscribers_count":5,"default_branch":"develop","last_synced_at":"2023-08-12T18:22:12.382Z","etag":null,"topics":["clojure","clojurescript","forms","react-jsonschema-form","schema"],"latest_commit_sha":null,"homepage":"","language":"Clojure","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/vodori.png","metadata":{"files":{"readme":"readme.md","changelog":"changelog.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-03-24T04:00:17.000Z","updated_at":"2022-10-21T19:14:36.000Z","dependencies_parsed_at":"2022-09-11T06:07:24.882Z","dependency_job_id":null,"html_url":"https://github.com/vodori/schema-forms","commit_stats":null,"previous_names":[],"tags_count":3,"template":null,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vodori%2Fschema-forms","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vodori%2Fschema-forms/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vodori%2Fschema-forms/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vodori%2Fschema-forms/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/vodori","download_url":"https://codeload.github.com/vodori/schema-forms/tar.gz/refs/heads/develop","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248225793,"owners_count":21068078,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["clojure","clojurescript","forms","react-jsonschema-form","schema"],"created_at":"2025-04-10T13:33:39.185Z","updated_at":"2025-04-10T13:33:39.248Z","avatar_url":"https://github.com/vodori.png","language":"Clojure","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Build Status](https://travis-ci.com/vodori/schema-forms.svg?branch=master)](https://travis-ci.com/vodori/schema-forms) [![Maven metadata URL](https://img.shields.io/maven-metadata/v/https/repo1.maven.org/maven2/com/vodori/schema-forms/maven-metadata.xml.svg)](https://mvnrepository.com/artifact/com.vodori/schema-forms)\n\n### schema-forms\n\nA Clojure library providing extensive conversions from prismatic schemas into json-schemas that are \ncompatible for use with Mozilla's [react-jsonschema-form](https://github.com/mozilla-services/react-jsonschema-form).\n\n### origin\n\nWe use this functionality to generate an admin UI from schemas that define configurable data \nin our applications. The conversion from prismatic schema to json-schema is likely the most\nuseful piece of this work but in the future we may open source the admin interface as well.\n\n___\n\n### installation \n\n```clojure\n[com.vodori/schema-forms \"0.1.2\"]\n```\n\n___\n\n### usage \n\n```clojure\n(require '[schema.core :as s])\n(require '[schema-forms.core :as sf])\n\n\n; simple example\n\n(s/defschema Person \n  {:firstName s/Str\n   :lastName  s/Str \n   :age       s/Num})\n\n(def json-schema (sf/prismatic-\u003ejson-schema Person))\n\n#_{:type \"object\",\n   :title \"Person\",\n   :properties\n   {:firstName {:type \"string\", :title \"First Name\"},\n    :lastName {:type \"string\", :title \"Last Name\"},\n    :age {:type \"number\", :title \"Age\"}},\n   :additionalProperties false,\n   :required [:firstName :lastName :age]}\n\n; https://jsfiddle.net/e7prdzkq/\n\n\n; recursive schemas\n\n(s/defschema RecursivePerson\n  {:firstName s/Str\n   :friends   [(s/recursive #'RecursivePerson)]})\n   \n(def json-schema (sf/prismatic-\u003ejson-schema RecursivePerson))\n\n#_{:type \"object\",\n   :title \"Recursive Person\",\n   :properties\n   {:firstName {:type \"string\", :title \"First Name\"},\n    :friends\n    {:type \"array\",\n     :items\n     {\"$ref\" \"#/definitions/schema-forms.core-test.RecursivePerson\"},\n     :minItems 0,\n     :title \"Friends\"}},\n   :additionalProperties false,\n   :required [:firstName :friends],\n   :definitions\n   {\"schema-forms.core-test.RecursivePerson\"\n    {:type \"object\",\n     :title \"Recursive Person\",\n     :properties\n     {:firstName {:type \"string\", :title \"First Name\"},\n      :friends\n      {:type \"array\",\n       :items\n       {\"$ref\" \"#/definitions/schema-forms.core-test.RecursivePerson\"},\n       :minItems 0,\n       :title \"Friends\"}},\n     :additionalProperties false,\n     :required [:firstName :friends]}}}\n\n; https://jsfiddle.net/zy4mogx5/\n\n\n; abstract maps\n\n(require '[schema.experimental.abstract-map :as sam])\n\n(s/defschema Location\n  (sam/abstract-map-schema :country\n    {:street s/Str}))\n\n(sam/extend-schema UnitedStatesLocation\n  Location [\"UNITED_STATES\"]\n  {:state (s/enum \"ALABAMA\" \"ALASKA\")})\n\n(sam/extend-schema CanadianLocation\n  Location [\"CANADA\"]\n  {:province (s/enum \"ALBERTA\" \"BRITISH_COLUMBIA\")})\n  \n(def json-schema (sf/prismatic-\u003ejson-schema Location))\n\n#_{:type \"object\",\n   :properties\n   {:country {:type \"string\", :enum #{\"CANADA\" \"UNITED_STATES\"}}},\n   :required [:country],\n   :dependencies\n   {:country\n    {:oneOf\n     [{:type \"object\",\n       :properties\n       {:street {:type \"string\", :title \"Street\"},\n        :state\n        {:type \"string\", :enum #{\"ALASKA\" \"ALABAMA\"}, :title \"State\"},\n        :country {:enum [\"UNITED_STATES\"]}},\n       :additionalProperties false,\n       :required [:street :state]}\n      {:type \"object\",\n       :properties\n       {:street {:type \"string\", :title \"Street\"},\n        :province\n        {:type \"string\",\n         :enum #{\"ALBERTA\" \"BRITISH_COLUMBIA\"},\n         :title \"Province\"},\n        :country {:enum [\"CANADA\"]}},\n       :additionalProperties false,\n       :required [:street :province]}]}}}\n\n; https://jsfiddle.net/e7prdzkq/1/\n       \n```\n\n___\n\n\n### bijections\n\nIt's common when you start trying to programmatically generate forms that sometimes the schema\nyou have isn't exactly the same as how you want it to display within the form. We bridge the \nconcept of similar but not the same by using [schema bijections](https://github.com/gfredericks/schema-bijections). \nSchema bijections provide a way to define transformations for schemas and data from the shape that is most suitable \nfor your codebase and the shape that is most suitable for use with react-jsonschema-form.\n\n\nA bijection is a function that receives a schema and returns a map describing the transformation process\nor else returns nil if the schema it received shouldn't be transformed. Here's an example bijection that\nconverts any prismatic schema or data of the form `(s/maybe {:firstName s/Str})` into \n`[(s/optional {:firstName s/Str})]` instead. The array version produces a more desirable user experience\nin the form when using react-jsonschema-form.\n\n\n```clojure\n(defn optional-maps-to-arrays-of-0-or-1-items [schema]\n  (when (and (instance? schema.core.Maybe schema) (map? (:schema schema)))\n    {:left        [(s/optional (:schema schema) \"\")]\n     :left-\u003eright (fn [values] (first values))\n     :right-\u003eleft (fn [value] (filterv some? [value]))\n     :right       schema}))\n\n(s/defschema Person\n  {:firstName              s/Str\n   :lastName               s/Str\n   (s/optional-key :friend) (s/maybe {:firstName s/Str\n                                      :lastName  s/Str \n                                      :age       s/Num})})\n     \n(def options {:bijections [optional-maps-to-arrays-of-0-or-1-items]})\n(def json-schema (sf/prismatic-\u003ejson-schema Person options))\n\n#_{:type \"object\",\n   :title \"Person\",\n   :properties\n   {:firstName {:type \"string\", :title \"First Name\"},\n    :lastName {:type \"string\", :title \"Last Name\"},\n    :friend\n    {:type \"array\",\n     :items\n     {:type \"object\",\n      :title \"Person\",\n      :properties\n      {:firstName {:type \"string\", :title \"First Name\"},\n       :lastName {:type \"string\", :title \"Last Name\"},\n       :age {:type \"number\", :title \"Age\"}},\n      :additionalProperties false,\n      :required [:firstName :lastName :age]},\n     :maxItems 1,\n     :minItems 0,\n     :title \"Friend\"}},\n   :additionalProperties false,\n   :required [:firstName :lastName]}\n\n; https://jsfiddle.net/e7prdzkq/2/\n\n```\n\n\nApplying bijections means that the data going in/out of the form needs to be in a slightly\ndifferent shape in order to be compatible with the transformed schema. This library provides\nfunctions you can invoke in order to transform your data in either direction.\n\n```clojure\n(let [schema     {:options (s/maybe {:enabled s/Bool})}\n      original   {:options {:enabled true}}\n      bijections [optional-maps-to-arrays-of-0-or-1-items]]\n  (prismatic-data-\u003ejson-schema-data schema original bijections))\n\n#_{:options [{:enabled true}]}\n\n(let [schema     {:options (s/maybe {:enabled s/Bool})}\n      from-form  {:options [{:enabled true}]}\n      bijections [optional-maps-to-arrays-of-0-or-1-items]]\n  (json-schema-data-\u003eprismatic-data schema from-form bijections))\n\n#_{:options {:enabled true}}\n\n```\n\n___\n\n\n### faq\n\n__Q__: Is the library compatible with Clojure(Script)? \n\n__A__: Not yet. This library doesn't need anything jvm specific but the bijection\ndependency would also need to be converted to Clojure(Script).\n\n\n__Q__: Can I use this if I don't use react-jsonschema-form? \n\n__A__: Yes, please give it a try but your mileage may vary. In our experience consumers of\njson-schema vary in their interpretation of the more advanced polymorphic dispatch features.\n\n\n__Q__: What about the ui-schema component of react-jsonschema-form? How can I control the rendering order\nand set additional display options?\n\n__A__: This needs some hammock time. A lot of that information just isn't present in a prismatic\nschema by default and part of the original goal of this conversion was to leverage prismatic schemas\nas-is.\n\n\n___\n\n### license\nThis project is licensed under [MIT license](http://opensource.org/licenses/MIT).\n\n\n\n\n\n\n\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvodori%2Fschema-forms","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvodori%2Fschema-forms","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvodori%2Fschema-forms/lists"}