├── .github └── workflows │ └── ci.yml ├── .gitignore ├── LICENSE ├── Makefile ├── README.md ├── deps.edn ├── dev └── user.clj ├── karma.conf.js ├── package-lock.json ├── package.json ├── pom.xml ├── resources ├── contexts │ ├── fluree │ │ ├── ledger │ │ │ ├── v1.edn │ │ │ └── v1.jsonld │ │ ├── v1.edn │ │ └── v1.json │ └── org │ │ ├── geojson │ │ └── geojson-ld │ │ │ ├── geojson-context.edn │ │ │ └── geojson-context.jsonld │ │ ├── imsglobal │ │ └── purl │ │ │ └── spec │ │ │ └── clr │ │ │ └── v1p0 │ │ │ └── context │ │ │ ├── clr_v1p0.edn │ │ │ └── clr_v1p0.jsonld │ │ ├── schema │ │ ├── latest.edn │ │ └── latest.jsonld │ │ ├── w3 │ │ └── www │ │ │ ├── 2018 │ │ │ └── credentials │ │ │ │ ├── v1.edn │ │ │ │ └── v1.jsonld │ │ │ └── ns │ │ │ ├── did │ │ │ ├── v1.edn │ │ │ └── v1.jsonld │ │ │ └── shacl │ │ │ ├── v1.edn │ │ │ └── v1.jsonld │ │ └── w3id │ │ └── security │ │ ├── v1.edn │ │ ├── v1.jsonld │ │ ├── v2.edn │ │ └── v2.jsonld ├── org.imsglobal.purl.spec.clr.v1p0.context.clr_v1p0.jsonld ├── org.imsglobal.spec.clr.vocab.edn ├── org.purl.dc.terms.edn ├── org.schema.edn ├── org.w3id.openbadges.edn ├── owl.edn ├── owl.edn.bak ├── rdfs.edn └── skos.edn ├── shadow-cljs.edn ├── src └── fluree │ ├── json_ld.cljc │ └── json_ld │ ├── impl │ ├── compact.cljc │ ├── context.cljc │ ├── expand.cljc │ ├── external.cljc │ ├── iri.cljc │ ├── normalize.cljc │ └── util.cljc │ └── processor │ ├── api.clj │ └── api.cljs └── test └── fluree └── json_ld ├── impl ├── compact_test.cljc ├── context_test.cljc ├── expand_test.cljc ├── iri_test.cljc └── normalize_test.cljc └── processor ├── api_test.clj └── api_test.cljs /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | on: [push] 3 | jobs: 4 | test: 5 | name: Run tests 6 | runs-on: ubuntu-latest 7 | steps: 8 | - name: Checkout 9 | uses: actions/checkout@v3 10 | 11 | - name: Prepare java 12 | uses: actions/setup-java@v3 13 | with: 14 | distribution: 'corretto' 15 | java-version: 17 16 | 17 | - name: Install clojure 18 | uses: DeLaGuardo/setup-clojure@9.5 19 | with: 20 | cli: 'latest' 21 | bb: 'latest' 22 | 23 | - name: Prep tests 24 | run: npm install 25 | 26 | - name: Run tests 27 | run: make test 28 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | /classes 3 | /checkouts 4 | *.jar 5 | *.class 6 | /.cpcache 7 | /.lein-* 8 | /.nrepl-history 9 | /.nrepl-port 10 | .hgignore 11 | .hg/ 12 | .cljs_node_repl/ 13 | .dir-locals.el 14 | test/browser 15 | test/nodejs 16 | **node_modules 17 | .shadow-cljs 18 | /.clj-kondo/ 19 | /.lsp/ 20 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC 2 | LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM 3 | CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 4 | 5 | 1. DEFINITIONS 6 | 7 | "Contribution" means: 8 | 9 | a) in the case of the initial Contributor, the initial code and 10 | documentation distributed under this Agreement, and 11 | 12 | b) in the case of each subsequent Contributor: 13 | 14 | i) changes to the Program, and 15 | 16 | ii) additions to the Program; 17 | 18 | where such changes and/or additions to the Program originate from and are 19 | distributed by that particular Contributor. A Contribution 'originates' from 20 | a Contributor if it was added to the Program by such Contributor itself or 21 | anyone acting on such Contributor's behalf. Contributions do not include 22 | additions to the Program which: (i) are separate modules of software 23 | distributed in conjunction with the Program under their own license 24 | agreement, and (ii) are not derivative works of the Program. 25 | 26 | "Contributor" means any person or entity that distributes the Program. 27 | 28 | "Licensed Patents" mean patent claims licensable by a Contributor which are 29 | necessarily infringed by the use or sale of its Contribution alone or when 30 | combined with the Program. 31 | 32 | "Program" means the Contributions distributed in accordance with this 33 | Agreement. 34 | 35 | "Recipient" means anyone who receives the Program under this Agreement, 36 | including all Contributors. 37 | 38 | 2. GRANT OF RIGHTS 39 | 40 | a) Subject to the terms of this Agreement, each Contributor hereby grants 41 | Recipient a non-exclusive, worldwide, royalty-free copyright license to 42 | reproduce, prepare derivative works of, publicly display, publicly perform, 43 | distribute and sublicense the Contribution of such Contributor, if any, and 44 | such derivative works, in source code and object code form. 45 | 46 | b) Subject to the terms of this Agreement, each Contributor hereby grants 47 | Recipient a non-exclusive, worldwide, royalty-free patent license under 48 | Licensed Patents to make, use, sell, offer to sell, import and otherwise 49 | transfer the Contribution of such Contributor, if any, in source code and 50 | object code form. This patent license shall apply to the combination of the 51 | Contribution and the Program if, at the time the Contribution is added by the 52 | Contributor, such addition of the Contribution causes such combination to be 53 | covered by the Licensed Patents. The patent license shall not apply to any 54 | other combinations which include the Contribution. No hardware per se is 55 | licensed hereunder. 56 | 57 | c) Recipient understands that although each Contributor grants the licenses 58 | to its Contributions set forth herein, no assurances are provided by any 59 | Contributor that the Program does not infringe the patent or other 60 | intellectual property rights of any other entity. Each Contributor disclaims 61 | any liability to Recipient for claims brought by any other entity based on 62 | infringement of intellectual property rights or otherwise. As a condition to 63 | exercising the rights and licenses granted hereunder, each Recipient hereby 64 | assumes sole responsibility to secure any other intellectual property rights 65 | needed, if any. For example, if a third party patent license is required to 66 | allow Recipient to distribute the Program, it is Recipient's responsibility 67 | to acquire that license before distributing the Program. 68 | 69 | d) Each Contributor represents that to its knowledge it has sufficient 70 | copyright rights in its Contribution, if any, to grant the copyright license 71 | set forth in this Agreement. 72 | 73 | 3. REQUIREMENTS 74 | 75 | A Contributor may choose to distribute the Program in object code form under 76 | its own license agreement, provided that: 77 | 78 | a) it complies with the terms and conditions of this Agreement; and 79 | 80 | b) its license agreement: 81 | 82 | i) effectively disclaims on behalf of all Contributors all warranties and 83 | conditions, express and implied, including warranties or conditions of title 84 | and non-infringement, and implied warranties or conditions of merchantability 85 | and fitness for a particular purpose; 86 | 87 | ii) effectively excludes on behalf of all Contributors all liability for 88 | damages, including direct, indirect, special, incidental and consequential 89 | damages, such as lost profits; 90 | 91 | iii) states that any provisions which differ from this Agreement are offered 92 | by that Contributor alone and not by any other party; and 93 | 94 | iv) states that source code for the Program is available from such 95 | Contributor, and informs licensees how to obtain it in a reasonable manner on 96 | or through a medium customarily used for software exchange. 97 | 98 | When the Program is made available in source code form: 99 | 100 | a) it must be made available under this Agreement; and 101 | 102 | b) a copy of this Agreement must be included with each copy of the Program. 103 | 104 | Contributors may not remove or alter any copyright notices contained within 105 | the Program. 106 | 107 | Each Contributor must identify itself as the originator of its Contribution, 108 | if any, in a manner that reasonably allows subsequent Recipients to identify 109 | the originator of the Contribution. 110 | 111 | 4. COMMERCIAL DISTRIBUTION 112 | 113 | Commercial distributors of software may accept certain responsibilities with 114 | respect to end users, business partners and the like. While this license is 115 | intended to facilitate the commercial use of the Program, the Contributor who 116 | includes the Program in a commercial product offering should do so in a 117 | manner which does not create potential liability for other Contributors. 118 | Therefore, if a Contributor includes the Program in a commercial product 119 | offering, such Contributor ("Commercial Contributor") hereby agrees to defend 120 | and indemnify every other Contributor ("Indemnified Contributor") against any 121 | losses, damages and costs (collectively "Losses") arising from claims, 122 | lawsuits and other legal actions brought by a third party against the 123 | Indemnified Contributor to the extent caused by the acts or omissions of such 124 | Commercial Contributor in connection with its distribution of the Program in 125 | a commercial product offering. The obligations in this section do not apply 126 | to any claims or Losses relating to any actual or alleged intellectual 127 | property infringement. In order to qualify, an Indemnified Contributor must: 128 | a) promptly notify the Commercial Contributor in writing of such claim, and 129 | b) allow the Commercial Contributor tocontrol, and cooperate with the 130 | Commercial Contributor in, the defense and any related settlement 131 | negotiations. The Indemnified Contributor may participate in any such claim 132 | at its own expense. 133 | 134 | For example, a Contributor might include the Program in a commercial product 135 | offering, Product X. That Contributor is then a Commercial Contributor. If 136 | that Commercial Contributor then makes performance claims, or offers 137 | warranties related to Product X, those performance claims and warranties are 138 | such Commercial Contributor's responsibility alone. Under this section, the 139 | Commercial Contributor would have to defend claims against the other 140 | Contributors related to those performance claims and warranties, and if a 141 | court requires any other Contributor to pay any damages as a result, the 142 | Commercial Contributor must pay those damages. 143 | 144 | 5. NO WARRANTY 145 | 146 | EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON 147 | AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER 148 | EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR 149 | CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A 150 | PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the 151 | appropriateness of using and distributing the Program and assumes all risks 152 | associated with its exercise of rights under this Agreement , including but 153 | not limited to the risks and costs of program errors, compliance with 154 | applicable laws, damage to or loss of data, programs or equipment, and 155 | unavailability or interruption of operations. 156 | 157 | 6. DISCLAIMER OF LIABILITY 158 | 159 | EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY 160 | CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, 161 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION 162 | LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 163 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 164 | ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE 165 | EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY 166 | OF SUCH DAMAGES. 167 | 168 | 7. GENERAL 169 | 170 | If any provision of this Agreement is invalid or unenforceable under 171 | applicable law, it shall not affect the validity or enforceability of the 172 | remainder of the terms of this Agreement, and without further action by the 173 | parties hereto, such provision shall be reformed to the minimum extent 174 | necessary to make such provision valid and enforceable. 175 | 176 | If Recipient institutes patent litigation against any entity (including a 177 | cross-claim or counterclaim in a lawsuit) alleging that the Program itself 178 | (excluding combinations of the Program with other software or hardware) 179 | infringes such Recipient's patent(s), then such Recipient's rights granted 180 | under Section 2(b) shall terminate as of the date such litigation is filed. 181 | 182 | All Recipient's rights under this Agreement shall terminate if it fails to 183 | comply with any of the material terms or conditions of this Agreement and 184 | does not cure such failure in a reasonable period of time after becoming 185 | aware of such noncompliance. If all Recipient's rights under this Agreement 186 | terminate, Recipient agrees to cease use and distribution of the Program as 187 | soon as reasonably practicable. However, Recipient's obligations under this 188 | Agreement and any licenses granted by Recipient relating to the Program shall 189 | continue and survive. 190 | 191 | Everyone is permitted to copy and distribute copies of this Agreement, but in 192 | order to avoid inconsistency the Agreement is copyrighted and may only be 193 | modified in the following manner. The Agreement Steward reserves the right to 194 | publish new versions (including revisions) of this Agreement from time to 195 | time. No one other than the Agreement Steward has the right to modify this 196 | Agreement. The Eclipse Foundation is the initial Agreement Steward. The 197 | Eclipse Foundation may assign the responsibility to serve as the Agreement 198 | Steward to a suitable separate entity. Each new version of the Agreement will 199 | be given a distinguishing version number. The Program (including 200 | Contributions) may always be distributed subject to the version of the 201 | Agreement under which it was received. In addition, after a new version of 202 | the Agreement is published, Contributor may elect to distribute the Program 203 | (including its Contributions) under the new version. Except as expressly 204 | stated in Sections 2(a) and 2(b) above, Recipient receives no rights or 205 | licenses to the intellectual property of any Contributor under this 206 | Agreement, whether expressly, by implication, estoppel or otherwise. All 207 | rights in the Program not expressly granted under this Agreement are 208 | reserved. 209 | 210 | This Agreement is governed by the laws of the State of New York and the 211 | intellectual property laws of the United States of America. No party to this 212 | Agreement will bring a legal action under this Agreement more than one year 213 | after the cause of action arose. Each party waives its rights to a jury trial 214 | in any resulting litigation. 215 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: test jar install deploy clean edn-contexts 2 | 3 | SOURCES := $(shell find src) 4 | 5 | target/fluree-json-ld.jar: pom.xml deps.edn src/deps.cljs $(SOURCES) 6 | clojure -X:jar 7 | 8 | src/deps.cljs: package.json 9 | clojure -M:js-deps 10 | 11 | resources/contexts/%.edn: resources/contexts/%.jsonld 12 | clojure -X:build-edn-context :source '"$(subst resources/,,$<)"' :dest '"$(subst resources/,,$@)"' 13 | 14 | CONTEXTS := $(shell find resources/contexts -name '*.jsonld') 15 | EDN_CONTEXTS := $(CONTEXTS:.jsonld=.edn) 16 | 17 | edn-contexts: $(EDN_CONTEXTS) 18 | 19 | pom.xml: deps.edn 20 | clojure -Spom 21 | 22 | cljtest: 23 | clojure -X:test 24 | 25 | nodetest: 26 | npx shadow-cljs release nodejs-test 27 | 28 | browsertest: 29 | npx shadow-cljs release browser-test 30 | ./node_modules/karma/bin/karma start --single-run 31 | 32 | cljstest: nodetest browsertest 33 | 34 | test: cljtest cljstest 35 | 36 | jar: target/fluree-json-ld.jar 37 | 38 | install: target/fluree-json-ld.jar 39 | clojure -X:install 40 | 41 | # You'll need to set the env vars CLOJARS_USERNAME & CLOJARS_PASSWORD 42 | # (which must be a Clojars deploy token now) to use this. 43 | deploy: target/fluree-json-ld.jar 44 | clojure -X:deploy 45 | 46 | clean: 47 | rm -rf target 48 | rm -rf node_modules 49 | rm -rf test/nodejs 50 | rm -rf test/browser 51 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # json-ld 2 | 3 | A Clojure(script) JSON-LD library. 4 | 5 | API in the fluree.json-ld namespace. 6 | 7 | ## Usage 8 | 9 | Run the project's tests: 10 | 11 | $ make test 12 | 13 | Build a deployable jar of this library: 14 | 15 | $ make jar 16 | 17 | Install it locally: 18 | 19 | $ make install 20 | 21 | Deploy it to Clojars -- needs `CLOJARS_USERNAME` and `CLOJARS_PASSWORD` environment variables: 22 | 23 | $ make deploy 24 | 25 | ## License 26 | 27 | Copyright © 2021 Fluree, PBC 28 | 29 | Distributed under the Eclipse Public License either version 1.0 or (at 30 | your option) any later version. 31 | -------------------------------------------------------------------------------- /deps.edn: -------------------------------------------------------------------------------- 1 | {:paths ["src" "resources"] 2 | 3 | :deps {org.clojure/clojure {:mvn/version "1.11.1"} 4 | org.clojure/clojurescript {:mvn/version "1.11.60"} 5 | com.apicatalog/titanium-json-ld {:mvn/version "1.3.2"} 6 | org.glassfish/jakarta.json {:mvn/version "2.0.1"} 7 | org.glassfish/javax.json {:mvn/version "1.1.4"} 8 | javax.json/javax.json-api {:mvn/version "1.1.4"} 9 | io.setl/rdf-urdna {:mvn/version "1.2"} 10 | metosin/jsonista {:mvn/version "0.3.7"}} 11 | 12 | :aliases 13 | {:mvn/group-id com.fluree 14 | :mvn/artifact-id json-ld 15 | :mvn/version "0.1.0" 16 | 17 | :dev 18 | {:extra-paths ["dev", "test"] 19 | :extra-deps {org.clojure/tools.namespace {:mvn/version "1.4.4"} 20 | cheshire/cheshire {:mvn/version "5.11.0"} 21 | thheller/shadow-cljs {:mvn/version "2.23.1"}} 22 | :main-opts ["-e" "(require,'user)" 23 | "-e" "(in-ns,'user)"]} 24 | 25 | :test 26 | {:extra-paths ["test"] 27 | :extra-deps {lambdaisland/kaocha {:mvn/version "1.85.1342"}} 28 | :exec-fn kaocha.runner/exec-fn 29 | :exec-args {}} 30 | 31 | :js-deps 32 | {:extra-deps {com.timetraveltoaster/target-bundle-libs {:mvn/version "RELEASE"}} 33 | :main-opts ["-m" "target-bundle-libs.core"]} 34 | 35 | :jar 36 | {:replace-deps {com.github.seancorfield/depstar {:mvn/version "2.1.303"}} 37 | :exec-fn hf.depstar/jar 38 | :exec-args {:jar "target/fluree-json-ld.jar" 39 | :group-id :mvn/group-id 40 | :artifact-id :mvn/artifact-id 41 | :version :mvn/version 42 | :sync-pom true}} 43 | 44 | :install 45 | {:extra-deps {slipset/deps-deploy {:mvn/version "RELEASE"}} 46 | :exec-fn deps-deploy.deps-deploy/deploy 47 | :exec-args {:installer :local 48 | :artifact "target/fluree-json-ld.jar"}} 49 | 50 | :deploy 51 | {:extra-deps {slipset/deps-deploy {:mvn/version "RELEASE"}} 52 | :exec-fn deps-deploy.deps-deploy/deploy 53 | :exec-args {:installer :remote 54 | :sign-releases? false 55 | :artifact "target/fluree-json-ld.jar"}} 56 | 57 | :build-edn-context 58 | {:extra-paths ["dev"] 59 | :extra-deps {org.clojure/tools.namespace {:mvn/version "1.4.4"} 60 | cheshire/cheshire {:mvn/version "5.11.0"}} 61 | :exec-fn user/parse-context-file 62 | :exec-args {:source nil 63 | :dest nil}}}} 64 | -------------------------------------------------------------------------------- /dev/user.clj: -------------------------------------------------------------------------------- 1 | (ns user 2 | (:require [clojure.java.io :as io] 3 | [clojure.tools.namespace.repl :as tn :refer [refresh refresh-all]] 4 | [fluree.json-ld :as json-ld] 5 | [fluree.json-ld.impl.external :as external] 6 | [fluree.json-ld.impl.expand :as expand] 7 | [cheshire.core :as cheshire] 8 | [clojure.java.io :as io] 9 | [clojure.pprint :as pprint]) 10 | (:import (clojure.lang ExceptionInfo))) 11 | 12 | (defn parse-context-file 13 | [{:keys [source dest]}] 14 | (let [json (-> source io/resource slurp)] 15 | (when-not json 16 | (throw (ex-info (str "Context unable to be loaded from file: " source ".") 17 | {:status 400 :error :json-ld/invalid-context}))) 18 | (->> json 19 | cheshire/parse-string 20 | json-ld/parse-context 21 | pprint/pprint 22 | with-out-str 23 | (spit (io/file "resources" dest))))) 24 | 25 | (defn parse-context 26 | "Parses a single context and saves to corresponding .edn file." 27 | [context] 28 | (let [{:keys [source] :as files} (get external/context->file context)] 29 | (try 30 | (parse-context-file files) 31 | (catch ExceptionInfo _ 32 | (throw (ex-info (str "Unable to load context " context " from file: " source ".") 33 | {:status 400, :error :json-ld/invalid-context})))))) 34 | 35 | 36 | (defn re-parse-all-contexts 37 | "Re-parses and saves all external context files" 38 | [] 39 | (let [externals (keys external/context->file)] 40 | (doseq [context externals] 41 | (println "Processing: " context) 42 | (parse-context context)))) 43 | 44 | 45 | (comment 46 | 47 | (json-ld/expand {"@context" {"gist" "https://ontologies.semanticarts.com/gist/", 48 | "owl" "http://www.w3.org/2002/07/owl#", 49 | "skos" "http://www.w3.org/2004/02/skos/core#", 50 | "xsd" "http://www.w3.org/2001/XMLSchema#"}, 51 | "@id" "gist:CoherentUnit", 52 | "skos:scopeNote" [{"@type" "xsd:string", "@value" "Coherent unit is the physics term for this, informally you might think of it as the standard unit for a given dimension."} 53 | {"@type" "xsd:string", "@value" "In principle, the CoherentUnit for a ProductUnit or RatioUnit can be inferred by recursively decomposing the products and ratios into their respective CoherentUnits, bottoming out in SimpleUnits"}], 54 | "@type" "owl:Class"}) 55 | 56 | (json-ld/expand {"@context" {"@base" "https://base.com/base/iri" 57 | "@vocab" "https://vocab.com/vocab/iri/" 58 | "iriProperty" {"@type" "@id"}} 59 | "@id" "#joebob", 60 | "@type" "Joey" 61 | "name" "Joe Bob" 62 | "iriProperty" "#a-relative-id"}) 63 | 64 | (json-ld/expand {"@context" ["https://www.w3.org/2018/credentials/v1" "https://flur.ee/ns/block"], 65 | 66 | "credentialSubject" {"message" "Another commit"} 67 | "type" ["VerifiableCredential"]}) 68 | 69 | (json-ld/expand {"@context" ["https://www.w3.org/2018/credentials/v1" "https://flur.ee/ns/block"], 70 | "type" ["VerifiableCredential"] 71 | "credentialSubject" {"message" "Another commit"}, 72 | "id" "blah", 73 | "issuanceDate" "2021-12-26T10:55:09.579350Z", 74 | "issuer" "did:fluree:TfCzWTrXqF16hvKGjcYiLxRoYJ1B8a6UMH6",}) 75 | 76 | 77 | (json-ld/parse-context "https://www.w3.org/2018/credentials/v1") 78 | 79 | (parse-context "https://ns.flur.ee/ledger/v1") 80 | 81 | (parse-context "https://geojson.org/geojson-ld/geojson-context.jsonld") 82 | 83 | (re-parse-all-contexts) 84 | 85 | (json-ld/parse-context ["https://flur.ee/ns/block" 86 | {"schema" "http://schema.org/"}])) 87 | -------------------------------------------------------------------------------- /karma.conf.js: -------------------------------------------------------------------------------- 1 | module.exports = function (config) { 2 | config.set({ 3 | browsers: ['ChromeHeadless'], 4 | // The directory where the output file lives 5 | basePath: 'test/browser/', 6 | // The file itself 7 | files: ['browser-tests.js'], 8 | frameworks: ['cljs-test'], 9 | plugins: ['karma-cljs-test', 'karma-chrome-launcher'], 10 | colors: true, 11 | logLevel: config.LOG_INFO, 12 | client: { 13 | args: ["shadow.test.karma.init"], 14 | singleRun: true 15 | } 16 | }) 17 | }; 18 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "devDependencies": { 3 | "karma": "6.4.0", 4 | "karma-chrome-launcher": "3.1.1", 5 | "karma-cljs-test": "0.1.0", 6 | "shadow-cljs": "2.20.5" 7 | }, 8 | "dependencies": { 9 | "jsonld": "^8.1.0" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | com.fluree 5 | json-ld 6 | 0.1.0 7 | json-ld 8 | Fluree JSON-LD Library 9 | https://github.com/com.fluree/json-ld 10 | 11 | 12 | Eclipse Public License 13 | http://www.eclipse.org/legal/epl-v10.html 14 | 15 | 16 | 17 | 18 | Wmorgan 19 | 20 | 21 | 22 | https://github.com/com.fluree/json-ld 23 | scm:git:git://github.com/com.fluree/json-ld.git 24 | scm:git:ssh://git@github.com/com.fluree/json-ld.git 25 | HEAD 26 | 27 | 28 | 29 | org.clojure 30 | clojure 31 | 1.11.1 32 | 33 | 34 | org.clojure 35 | clojurescript 36 | 1.11.60 37 | 38 | 39 | com.apicatalog 40 | titanium-json-ld 41 | 1.3.1 42 | 43 | 44 | org.glassfish 45 | jakarta.json 46 | 2.0.1 47 | 48 | 49 | org.glassfish 50 | javax.json 51 | 1.1.4 52 | 53 | 54 | javax.json 55 | javax.json-api 56 | 1.1.4 57 | 58 | 59 | io.setl 60 | rdf-urdna 61 | 1.2 62 | 63 | 64 | metosin 65 | jsonista 66 | 0.3.6 67 | 68 | 69 | 70 | src 71 | 72 | 73 | 74 | clojars 75 | https://repo.clojars.org/ 76 | 77 | 78 | 79 | 80 | clojars 81 | Clojars repository 82 | https://clojars.org/repo 83 | 84 | 85 | 86 | -------------------------------------------------------------------------------- /resources/contexts/fluree/ledger/v1.edn: -------------------------------------------------------------------------------- 1 | {"message" {:id "https://ns.flur.ee/ledger#message"}, 2 | "role" {:id "https://ns.flur.ee/ledger#role", :type :id}, 3 | "Index" {:id "https://ns.flur.ee/ledger#Index"}, 4 | "targetClass" 5 | {:id "https://ns.flur.ee/ledger#targetClass", :type :id}, 6 | "index" {:id "https://ns.flur.ee/ledger#index"}, 7 | "allNodes" {:id "https://ns.flur.ee/ledger#allNodes"}, 8 | "delete" {:id "https://ns.flur.ee/ledger#delete"}, 9 | "Context" {:id "https://ns.flur.ee/ledger#Context"}, 10 | "updates" {:id "https://ns.flur.ee/ledger#updates"}, 11 | "branch" {:id "https://ns.flur.ee/ledger#branch"}, 12 | "issuer" 13 | {:id "https://www.w3.org/2018/credentials#issuer", :type :id}, 14 | "contains" 15 | {:id "https://ns.flur.ee/ledger#contains", 16 | :type :id, 17 | :container :list}, 18 | "author" {:id "https://ns.flur.ee/ledger#author"}, 19 | "txn" {:id "https://ns.flur.ee/ledger#txn"}, 20 | "FNS" {:id "https://ns.flur.ee/ledger#FNS"}, 21 | "creds" {:id "https://www.w3.org/2018/credentials#"}, 22 | "path" {:id "https://ns.flur.ee/ledger#path", :type :id}, 23 | "DB" {:id "https://ns.flur.ee/ledger#DB"}, 24 | "v" 25 | {:id "https://ns.flur.ee/ledger#v", 26 | :type "http://www.w3.org/2001/XMLSchema#decimal"}, 27 | "id" {:id "@id"}, 28 | "update" {:id "https://ns.flur.ee/ledger#update"}, 29 | "allow" {:id "https://ns.flur.ee/ledger#allow", :type :id}, 30 | "flakes" 31 | {:id "https://ns.flur.ee/ledger#flakes", 32 | :type "http://www.w3.org/2001/XMLSchema#long"}, 33 | "Role" {:id "https://ns.flur.ee/ledger#Role"}, 34 | :type-key "type", 35 | "Commit" {:id "https://ns.flur.ee/ledger#Commit"}, 36 | "tag" {:id "https://ns.flur.ee/ledger#tag"}, 37 | "commit" {:id "https://ns.flur.ee/ledger#commit", :type :id}, 38 | "modify" {:id "https://ns.flur.ee/ledger#modify"}, 39 | "address" {:id "https://ns.flur.ee/ledger#address"}, 40 | "previous" {:id "https://ns.flur.ee/ledger#previous", :type :id}, 41 | "fluree" {:id "https://ns.flur.ee/ledger#"}, 42 | "action" {:id "https://ns.flur.ee/ledger#action", :type :id}, 43 | "retract" 44 | {:id "https://ns.flur.ee/ledger#retract", :container :graph}, 45 | "functions" {:id "https://ns.flur.ee/ledger#function", :type :id}, 46 | "property" {:id "https://ns.flur.ee/ledger#property", :type :id}, 47 | "time" {:id "https://ns.flur.ee/ledger#time"}, 48 | "t" 49 | {:id "https://ns.flur.ee/ledger#t", 50 | :type "http://www.w3.org/2001/XMLSchema#long"}, 51 | "rdfs" {:id "http://www.w3.org/2000/01/rdf-schema#"}, 52 | "tx" {:id "https://ns.flur.ee/ledger#tx", :type :id}, 53 | "type" {:id "@type", :type? true}, 54 | "DID" {:id "https://ns.flur.ee/ledger#DID"}, 55 | "create" {:id "https://ns.flur.ee/ledger#create"}, 56 | "targetRole" {:id "https://ns.flur.ee/ledger#targetRole", :type :id}, 57 | "alias" {:id "https://ns.flur.ee/ledger#alias"}, 58 | "Policy" {:id "https://ns.flur.ee/ledger#Policy"}, 59 | "targetNode" {:id "https://ns.flur.ee/ledger#targetNode", :type :id}, 60 | "size" 61 | {:id "https://ns.flur.ee/ledger#size", 62 | :type "http://www.w3.org/2001/XMLSchema#long"}, 63 | "Function" {:id "https://ns.flur.ee/ledger#Function"}, 64 | :version 1.1, 65 | "CommitProof" {:id "https://ns.flur.ee/ledger#CommitProof"}, 66 | "defaultContext" 67 | {:id "https://ns.flur.ee/ledger#defaultContext", :type :id}, 68 | "data" {:id "https://ns.flur.ee/ledger#data", :type :id}, 69 | "view" {:id "https://ns.flur.ee/ledger#view"}, 70 | "equals" 71 | {:id "https://ns.flur.ee/ledger#equals", :type :id, :container :list}, 72 | "skos" {:id "http://www.w3.org/2008/05/skos#"}, 73 | "code" {:id "https://ns.flur.ee/ledger#code"}, 74 | "assert" {:id "https://ns.flur.ee/ledger#assert", :container :graph}, 75 | "ns" {:id "https://ns.flur.ee/ledger#ns", :type :id}, 76 | "ledger" {:id "https://ns.flur.ee/ledger#ledger"}, 77 | "xsd" {:id "http://www.w3.org/2001/XMLSchema#"}} 78 | -------------------------------------------------------------------------------- /resources/contexts/fluree/ledger/v1.jsonld: -------------------------------------------------------------------------------- 1 | { 2 | "@context": { 3 | "@version": 1.1, 4 | "id": "@id", 5 | "type": "@type", 6 | "fluree": "https://ns.flur.ee/ledger#", 7 | "xsd": "http://www.w3.org/2001/XMLSchema#", 8 | "rdfs": "http://www.w3.org/2000/01/rdf-schema#", 9 | "skos": "http://www.w3.org/2008/05/skos#", 10 | "creds": "https://www.w3.org/2018/credentials#", 11 | "CommitProof": "fluree:CommitProof", 12 | "Commit": "fluree:Commit", 13 | "Index": "fluree:Index", 14 | "DB": "fluree:DB", 15 | "FNS": "fluree:FNS", 16 | "address": "fluree:address", 17 | "time": "fluree:time", 18 | "index": "fluree:index", 19 | "updates": "fluree:updates", 20 | "tag": "fluree:tag", 21 | "ledger": "fluree:ledger", 22 | "alias": "fluree:alias", 23 | "author": "fluree:author", 24 | "txn": "fluree:txn", 25 | "tx": { 26 | "@id": "fluree:tx", 27 | "@type": "@id" 28 | }, 29 | "commit": { 30 | "@id": "fluree:commit", 31 | "@type": "@id" 32 | }, 33 | "previous": { 34 | "@id": "fluree:previous", 35 | "@type": "@id" 36 | }, 37 | "t": { 38 | "@id": "fluree:t", 39 | "@type": "xsd:long" 40 | }, 41 | "v": { 42 | "@id": "fluree:v", 43 | "@type": "xsd:decimal" 44 | }, 45 | "issuer": { 46 | "@id": "creds:issuer", 47 | "@type": "@id" 48 | }, 49 | "flakes": { 50 | "@id": "fluree:flakes", 51 | "@type": "xsd:long" 52 | }, 53 | "size": { 54 | "@id": "fluree:size", 55 | "@type": "xsd:long" 56 | }, 57 | "data": { 58 | "@id": "fluree:data", 59 | "@type": "@id" 60 | }, 61 | "ns": { 62 | "@id": "fluree:ns", 63 | "@type": "@id" 64 | }, 65 | "assert": { 66 | "@id": "fluree:assert", 67 | "@container": "@graph" 68 | }, 69 | "retract": { 70 | "@id": "fluree:retract", 71 | "@container": "@graph" 72 | }, 73 | "message": "fluree:message", 74 | "branch": "fluree:branch", 75 | "defaultContext": { 76 | "@id": "fluree:defaultContext", 77 | "@type": "@id" 78 | }, 79 | "Policy": "fluree:Policy", 80 | "Role": "fluree:Role", 81 | "Function": "fluree:Function", 82 | "Context": "fluree:Context", 83 | "DID": "fluree:DID", 84 | "code": "fluree:code", 85 | "role": { 86 | "@id": "fluree:role", 87 | "@type": "@id" 88 | }, 89 | "functions": { 90 | "@id": "fluree:function", 91 | "@type": "@id" 92 | }, 93 | "action": { 94 | "@id": "fluree:action", 95 | "@type": "@id" 96 | }, 97 | "view": "fluree:view", 98 | "modify": "fluree:modify", 99 | "create": "fluree:create", 100 | "update": "fluree:update", 101 | "delete": "fluree:delete", 102 | "allNodes": "fluree:allNodes", 103 | "targetNode": { 104 | "@id": "fluree:targetNode", 105 | "@type": "@id" 106 | }, 107 | "targetClass": { 108 | "@id": "fluree:targetClass", 109 | "@type": "@id" 110 | }, 111 | "targetRole": { 112 | "@id": "fluree:targetRole", 113 | "@type": "@id" 114 | }, 115 | "allow": { 116 | "@id": "fluree:allow", 117 | "@type": "@id" 118 | }, 119 | "property": { 120 | "@id": "fluree:property", 121 | "@type": "@id" 122 | }, 123 | "path": { 124 | "@id": "fluree:path", 125 | "@type": "@id" 126 | }, 127 | "equals": { 128 | "@id": "fluree:equals", 129 | "@type": "@id", 130 | "@container": "@list" 131 | }, 132 | "contains": { 133 | "@id": "fluree:contains", 134 | "@type": "@id", 135 | "@container": "@list" 136 | } 137 | } 138 | } 139 | -------------------------------------------------------------------------------- /resources/contexts/fluree/v1.edn: -------------------------------------------------------------------------------- 1 | {:protected true 2 | "ledger" {:id "https://ns.flur.ee/ledger#ledger"} 3 | "defaultContext" {:type :json :id "https://ns.flur.ee/ledger#defaultContext" } 4 | "delete" {:type :json :id "https://ns.flur.ee/ledger#delete"} 5 | "insert" {:type :json :id "https://ns.flur.ee/ledger#insert"} 6 | "opts" {:type :json :id "https://ns.flur.ee/ledger#opts"} 7 | "where" {:type :json :id "https://ns.flur.ee/ledger#where"} 8 | "values" {:type :json :id "https://ns.flur.ee/ledger#values"}} 9 | -------------------------------------------------------------------------------- /resources/contexts/fluree/v1.json: -------------------------------------------------------------------------------- 1 | { 2 | "@context": { 3 | "@protected": true, 4 | "ledger": {"@id": "https://ns.flur.ee/ledger#ledger"}, 5 | "defaultContext": { 6 | "@type": "@json", 7 | "@id": "https://ns.flur.ee/ledger#defaultContext" 8 | }, 9 | "where": { 10 | "@type": "@json", 11 | "@id": "https://ns.flur.ee/ledger#where" 12 | }, 13 | "values": { 14 | "@type": "@json", 15 | "@id": "https://ns.flur.ee/ledger#values" 16 | }, 17 | "delete": { 18 | "@type": "@json", 19 | "@id": "https://ns.flur.ee/ledger#delete" 20 | }, 21 | "insert": { 22 | "@type": "@json", 23 | "@id": "https://ns.flur.ee/ledger#insert" 24 | }, 25 | "opts": { 26 | "@type": "@json", 27 | "@id": "https://ns.flur.ee/ledger#opts" 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /resources/contexts/org/geojson/geojson-ld/geojson-context.edn: -------------------------------------------------------------------------------- 1 | {"properties" {:id "https://purl.org/geojson/vocab#properties"}, 2 | "MultiLineString" 3 | {:id "https://purl.org/geojson/vocab#MultiLineString"}, 4 | "Feature" {:id "https://purl.org/geojson/vocab#Feature"}, 5 | "LineString" {:id "https://purl.org/geojson/vocab#LineString"}, 6 | "id" {:id "@id"}, 7 | "coordinates" 8 | {:container :list, :id "https://purl.org/geojson/vocab#coordinates"}, 9 | :type-key "type", 10 | "geometry" {:id "https://purl.org/geojson/vocab#geometry"}, 11 | "GeometryCollection" 12 | {:id "https://purl.org/geojson/vocab#GeometryCollection"}, 13 | "bbox" {:container :list, :id "https://purl.org/geojson/vocab#bbox"}, 14 | "Point" {:id "https://purl.org/geojson/vocab#Point"}, 15 | "type" {:id "@type", :type? true}, 16 | "FeatureCollection" 17 | {:id "https://purl.org/geojson/vocab#FeatureCollection"}, 18 | "geojson" {:id "https://purl.org/geojson/vocab#"}, 19 | "Polygon" {:id "https://purl.org/geojson/vocab#Polygon"}, 20 | "MultiPolygon" {:id "https://purl.org/geojson/vocab#MultiPolygon"}, 21 | "features" 22 | {:container :set, :id "https://purl.org/geojson/vocab#features"}, 23 | "MultiPoint" {:id "https://purl.org/geojson/vocab#MultiPoint"}} 24 | -------------------------------------------------------------------------------- /resources/contexts/org/geojson/geojson-ld/geojson-context.jsonld: -------------------------------------------------------------------------------- 1 | { 2 | "@context": { 3 | "geojson": "https://purl.org/geojson/vocab#", 4 | "Feature": "geojson:Feature", 5 | "FeatureCollection": "geojson:FeatureCollection", 6 | "GeometryCollection": "geojson:GeometryCollection", 7 | "LineString": "geojson:LineString", 8 | "MultiLineString": "geojson:MultiLineString", 9 | "MultiPoint": "geojson:MultiPoint", 10 | "MultiPolygon": "geojson:MultiPolygon", 11 | "Point": "geojson:Point", 12 | "Polygon": "geojson:Polygon", 13 | "bbox": { 14 | "@container": "@list", 15 | "@id": "geojson:bbox" 16 | }, 17 | "coordinates": { 18 | "@container": "@list", 19 | "@id": "geojson:coordinates" 20 | }, 21 | "features": { 22 | "@container": "@set", 23 | "@id": "geojson:features" 24 | }, 25 | "geometry": "geojson:geometry", 26 | "id": "@id", 27 | "properties": "geojson:properties", 28 | "type": "@type" 29 | } 30 | } -------------------------------------------------------------------------------- /resources/contexts/org/imsglobal/purl/spec/clr/v1p0/context/clr_v1p0.jsonld: -------------------------------------------------------------------------------- 1 | { 2 | "@context": { 3 | "id": "@id", 4 | "type": "@type", 5 | "clri": "https://purl.imsglobal.org/spec/clr/vocab#", 6 | "xsd": "http://www.w3.org/2001/XMLSchema#", 7 | "dtAchievement": "clri:dtAchievement", 8 | "dtAddress": "clri:dtAddress", 9 | "dtAlignment": "clri:dtAlignment", 10 | "dtArtifact": "clri:dtArtifact", 11 | "dtAssertion": "clri:dtAssertion", 12 | "dtAssociation": "clri:dtAssociation", 13 | "dtClr": "clri:dtClr", 14 | "dtCriteria": "clri:dtCriteria", 15 | "dtCryptographicKey": "clri:dtCryptographicKey", 16 | "dtEndorsement": "clri:dtEndorsement", 17 | "dtEndorsementClaim": "clri:dtEndorsementClaim", 18 | "dtEndorsementProfile": "clri:dtEndorsementProfile", 19 | "dtEvidence": "clri:dtEvidence", 20 | "dtExtensibleAchievementType": "clri:dtExtensibleAchievementType", 21 | "dtExtensibleAlignmentTargetType": "clri:dtExtensibleAlignmentTargetType", 22 | "dtExtensibleResultType": "clri:dtExtensibleResultType", 23 | "dtExtensibleSystemIdentifierType": "clri:dtExtensibleSystemIdentifierType", 24 | "dtIdentity": "clri:dtIdentity", 25 | "dtProfile": "clri:dtProfile", 26 | "dtResult": "clri:dtResult", 27 | "dtResultDescription": "clri:dtResultDescription", 28 | "dtRevocationList": "clri:dtRevocationList", 29 | "dtRubricCriterionLevel": "clri:dtRubricCriterionLevel", 30 | "dtSystemIdentifier": "clri:dtSystemIdentifier", 31 | "dtVerification": "clri:dtVerification", 32 | "dtCompactJws": { 33 | "@id": "clri:dtCompactJws", 34 | "@type": "xsd:string" 35 | }, 36 | "dtEnumExtString": { 37 | "@id": "clri:dtEnumExtString", 38 | "@type": "xsd:string" 39 | }, 40 | "dtIRI": { 41 | "@id": "clri:dtIRI", 42 | "@type": "xsd:normalizedString" 43 | }, 44 | "dtMarkdown": { 45 | "@id": "clri:dtMarkdown", 46 | "@type": "xsd:string" 47 | }, 48 | "dtUUID": { 49 | "@id": "clri:dtUUID", 50 | "@type": "xsd:string" 51 | }, 52 | "achievedLevel": "clri:dtIRI", 53 | "achievement": "clri:dtAchievement", 54 | "achievementType": "clri:dtExtensibleAchievementType", 55 | "achievements": { 56 | "@id": "clri:dtAchievement", 57 | "@container": "@set" 58 | }, 59 | "activityEndDate": { 60 | "@id": "clri:activityEndDate", 61 | "@type": "xsd:dateTime" 62 | }, 63 | "activityStartDate": { 64 | "@id": "clri:activityStartDate", 65 | "@type": "xsd:dateTime" 66 | }, 67 | "address": "clri:dtAddress", 68 | "addressCountry": { 69 | "@id": "clri:addressCountry", 70 | "@type": "xsd:string" 71 | }, 72 | "addressLocality": { 73 | "@id": "clri:addressLocality", 74 | "@type": "xsd:string" 75 | }, 76 | "addressRegion": { 77 | "@id": "clri:addressRegion", 78 | "@type": "xsd:string" 79 | }, 80 | "allowedValues": { 81 | "@id": "clri:allowedValues", 82 | "@type": "xsd:string", 83 | "@container": "@set" 84 | }, 85 | "artifacts": { 86 | "@id": "clri:dtArtifact", 87 | "@container": "@set" 88 | }, 89 | "assertions": { 90 | "@id": "clri:dtAssertion", 91 | "@container": "@set" 92 | }, 93 | "associationType": "clri:AssociationTypeDType", 94 | "associations": { 95 | "@id": "clri:dtAssociation", 96 | "@container": "@set" 97 | }, 98 | "birthDate": { 99 | "@id": "clri:birthDate", 100 | "@type": "xsd:date" 101 | }, 102 | "claim": "cred:claim", 103 | "clr": "clri:dtClr", 104 | "clrs": { 105 | "@id": "clri:dtClr", 106 | "@container": "@set" 107 | }, 108 | "creditsAvailable": { 109 | "@id": "clri:creditsAvailable", 110 | "@type": "xsd:float" 111 | }, 112 | "creditsEarned": { 113 | "@id": "clri:creditsEarned", 114 | "@type": "xsd:float" 115 | }, 116 | "endorsementComment": "obi:endorsementComment", 117 | "fieldOfStudy": { 118 | "@id": "clri:fieldOfStudy", 119 | "@type": "xsd:string" 120 | }, 121 | "humanCode": { 122 | "@id": "clri:humanCode", 123 | "@type": "xsd:string" 124 | }, 125 | "identifier": { 126 | "@id": "clri:identifier", 127 | "@type": "xsd:string" 128 | }, 129 | "identifierType": "clri:dtExtensibleSystemIdentifierType", 130 | "identifiers": { 131 | "@id": "clri:dtSystemIdentifier", 132 | "@container": "@set" 133 | }, 134 | "image": { 135 | "@id": "schema:image", 136 | "@type": "@id" 137 | }, 138 | "issuer": "obi:issuer", 139 | "learner": { 140 | "@id": "clri:learner", 141 | "@type": "@id" 142 | }, 143 | "level": { 144 | "@id": "clri:level", 145 | "@type": "xsd:string" 146 | }, 147 | "licenseNumber": { 148 | "@id": "clri:licenseNumber", 149 | "@type": "xsd:string" 150 | }, 151 | "narrative": "obi:narrative", 152 | "official": { 153 | "@id": "clri:official", 154 | "@type": "xsd:string" 155 | }, 156 | "owner": "sec:owner", 157 | "parentOrg": "obi:Profile", 158 | "partial": { 159 | "@id": "clri:partial", 160 | "@type": "xsd:boolean" 161 | }, 162 | "points": { 163 | "@id": "clri:points", 164 | "@type": "xsd:string" 165 | }, 166 | "postOfficeBoxNumber": { 167 | "@id": "clri:postOfficeBoxNumber", 168 | "@type": "xsd:string" 169 | }, 170 | "postalCode": { 171 | "@id": "clri:postalCode", 172 | "@type": "xsd:string" 173 | }, 174 | "publicKey": "sec:publicKey", 175 | "publisher": { 176 | "@id": "clri:publisher", 177 | "@type": "@id" 178 | }, 179 | "recipient": "obi:recipient", 180 | "requiredLevel": "clri:dtIRI", 181 | "requiredValue": { 182 | "@id": "clri:requiredValue", 183 | "@type": "xsd:string" 184 | }, 185 | "requirement": "obi:criteria", 186 | "resultDescription": "clri:dtIRI", 187 | "resultDescriptions": { 188 | "@id": "clri:dtResultDescription", 189 | "@container": "@set" 190 | }, 191 | "resultType": "clri:dtExtensibleResultType", 192 | "results": { 193 | "@id": "clri:dtResult", 194 | "@container": "@set" 195 | }, 196 | "role": { 197 | "@id": "clri:role", 198 | "@type": "xsd:string" 199 | }, 200 | "rubricCriterionLevels": { 201 | "@id": "clri:dtRubricCriterionLevel", 202 | "@container": "@set" 203 | }, 204 | "scopesOffered": { 205 | "@id": "clri:scopesOffered", 206 | "@type": "xsd:anyURI", 207 | "@container": "@set" 208 | }, 209 | "signedAssertions": { 210 | "@id": "clri:dtCompactJws", 211 | "@container": "@set" 212 | }, 213 | "signedClr": "clri:dtCompactJws", 214 | "signedClrs": { 215 | "@id": "clri:dtCompactJws", 216 | "@container": "@set" 217 | }, 218 | "signedEndorsements": { 219 | "@id": "clri:dtCompactJws", 220 | "@container": "@set" 221 | }, 222 | "source": "clri:dtProfile", 223 | "sourcedId": { 224 | "@id": "clri:sourcedId", 225 | "@type": "xsd:string" 226 | }, 227 | "specialization": { 228 | "@id": "clri:specialization", 229 | "@type": "xsd:string" 230 | }, 231 | "status": "clri:ResultStatusTypeDType", 232 | "streetAddress": { 233 | "@id": "clri:streetAddress", 234 | "@type": "xsd:string" 235 | }, 236 | "studentId": { 237 | "@id": "clri:studentId", 238 | "@type": "xsd:string" 239 | }, 240 | "targetId": "clri:dtIRI", 241 | "targetType": "clri:dtExtensibleAlignmentTargetType", 242 | "term": { 243 | "@id": "clri:term", 244 | "@type": "xsd:string" 245 | }, 246 | "title": { 247 | "@id": "clri:title", 248 | "@type": "xsd:string" 249 | }, 250 | "url": "schema:url", 251 | "value": { 252 | "@id": "clri:value", 253 | "@type": "xsd:string" 254 | }, 255 | "valueMax": { 256 | "@id": "clri:valueMax", 257 | "@type": "xsd:string" 258 | }, 259 | "valueMin": { 260 | "@id": "clri:valueMin", 261 | "@type": "xsd:string" 262 | }, 263 | "verification": "obi:verify", 264 | "Achievement": "dtAchievement", 265 | "Address": "dtAddress", 266 | "Alignment": "dtAlignment", 267 | "Artifact": "dtArtifact", 268 | "Assertion": "dtAssertion", 269 | "Association": "dtAssociation", 270 | "Clr": "dtClr", 271 | "Criteria": "dtCriteria", 272 | "CryptographicKey": "dtCryptographicKey", 273 | "Endorsement": "dtEndorsement", 274 | "EndorsementClaim": "dtEndorsementClaim", 275 | "EndorsementProfile": "dtEndorsementProfile", 276 | "Evidence": "dtEvidence", 277 | "ExtensibleAchievementType": "dtExtensibleAchievementType", 278 | "ExtensibleAlignmentTargetType": "dtExtensibleAlignmentTargetType", 279 | "ExtensibleResultType": "dtExtensibleResultType", 280 | "ExtensibleSystemIdentifierType": "dtExtensibleSystemIdentifierType", 281 | "Identity": "dtIdentity", 282 | "Profile": "dtProfile", 283 | "Result": "dtResult", 284 | "ResultDescription": "dtResultDescription", 285 | "RevocationList": "dtRevocationList", 286 | "RubricCriterionLevel": "dtRubricCriterionLevel", 287 | "SystemIdentifier": "dtSystemIdentifier", 288 | "Verification": "obi:VerificationObject", 289 | "CompactJws": "dtCompactJws", 290 | "EnumExtString": "dtEnumExtString", 291 | "IRI": "dtIRI", 292 | "Markdown": "dtMarkdown", 293 | "UUID": "dtUUID", 294 | "cred": "https://w3id.org/credentials/", 295 | "dc": "http://purl.org/dc/terms/", 296 | "obi": "https://w3id.org/openbadges#", 297 | "schema": "http://schema.org/", 298 | "sec": "https://w3id.org/security#", 299 | "additionalName": "schema:additionalName", 300 | "alignments": "obi:alignment", 301 | "allowedOrigins": "obi:allowedOrigins", 302 | "audience": "obi:audience", 303 | "authorizationUrl": { 304 | "@id": "clri:authorizationUrl", 305 | "@type": "@id" 306 | }, 307 | "creator": "dc:creator", 308 | "description": "schema:description", 309 | "email": "schema:email", 310 | "endorsements": "cred:credential", 311 | "expires": { 312 | "@id": "sec:expiration", 313 | "@type": "xsd:dateTime" 314 | }, 315 | "evidence": "obi:evidence", 316 | "familyName": "schema:familyName", 317 | "genre": "schema:genre", 318 | "givenName": "schema:givenName", 319 | "hashed": "obi:hashed", 320 | "identity": "obi:identityHash", 321 | "issuedOn": "obi:issueDate", 322 | "name": "schema:name", 323 | "privacyPolicyUrl": { 324 | "@id": "clri:privacyPolicyUrl", 325 | "@type": "@id" 326 | }, 327 | "publicKeyPem": "sec:publicKeyPem", 328 | "registrationUrl": { 329 | "@id": "clri:registrationUrl", 330 | "@type": "@id" 331 | }, 332 | "revocationList": "obi:revocationList", 333 | "revocationReason": "obi:revocationReason", 334 | "revoked": "obi:revoked", 335 | "revokedAssertions": "obi:revokedAssertions", 336 | "salt": "obi:salt", 337 | "startsWith": "obi:startsWith", 338 | "tags": "schema:keywords", 339 | "targetCode": "obi:targetCode", 340 | "targetDescription": "schema:targetDescription", 341 | "targetFramework": "schema:educationalFramework", 342 | "targetName": "schema:targetName", 343 | "targetUrl": "schema:targetUrl", 344 | "telephone": "schema:telephone", 345 | "termsOfServiceUrl": { 346 | "@id": "clri:termsOfServiceUrl", 347 | "@type": "@id" 348 | }, 349 | "tokenUrl": { 350 | "@id": "clri:tokenUrl", 351 | "@type": "@id" 352 | }, 353 | "verificationProperty": "obi:verificationProperty", 354 | "Hosted": "obi:hosted", 355 | "Signed": "obi:signed" 356 | } 357 | } -------------------------------------------------------------------------------- /resources/contexts/org/w3/www/2018/credentials/v1.edn: -------------------------------------------------------------------------------- 1 | {"EcdsaSecp256k1Signature2019" 2 | {:id "https://w3id.org/security#EcdsaSecp256k1Signature2019", 3 | :context 4 | {"created" 5 | {:id "http://purl.org/dc/terms/created", 6 | :type "http://www.w3.org/2001/XMLSchema#dateTime"}, 7 | "jws" {:id "https://w3id.org/security#jws"}, 8 | "proofPurpose" 9 | {:id "https://w3id.org/security#proofPurpose", 10 | :type :vocab, 11 | :context 12 | {:type-key "type", 13 | :version 1.1, 14 | :protected true, 15 | "id" {:id "@id"}, 16 | "type" {:id "@type", :type? true}, 17 | "sec" {:id "https://w3id.org/security#"}, 18 | "assertionMethod" 19 | {:id "https://w3id.org/security#assertionMethod", 20 | :type :id, 21 | :container :set}, 22 | "authentication" 23 | {:id "https://w3id.org/security#authenticationMethod", 24 | :type :id, 25 | :container :set}}}, 26 | "id" {:id "@id"}, 27 | "challenge" {:id "https://w3id.org/security#challenge"}, 28 | :type-key "type", 29 | "expires" 30 | {:id "https://w3id.org/security#expiration", 31 | :type "http://www.w3.org/2001/XMLSchema#dateTime"}, 32 | "domain" {:id "https://w3id.org/security#domain"}, 33 | "verificationMethod" 34 | {:id "https://w3id.org/security#verificationMethod", :type :id}, 35 | "proofValue" {:id "https://w3id.org/security#proofValue"}, 36 | "type" {:id "@type", :type? true}, 37 | :protected true, 38 | "nonce" {:id "https://w3id.org/security#nonce"}, 39 | :version 1.1, 40 | "sec" {:id "https://w3id.org/security#"}, 41 | "xsd" {:id "http://www.w3.org/2001/XMLSchema#"}}}, 42 | "id" {:id "@id"}, 43 | "Ed25519Signature2018" 44 | {:id "https://w3id.org/security#Ed25519Signature2018", 45 | :context 46 | {"created" 47 | {:id "http://purl.org/dc/terms/created", 48 | :type "http://www.w3.org/2001/XMLSchema#dateTime"}, 49 | "jws" {:id "https://w3id.org/security#jws"}, 50 | "proofPurpose" 51 | {:id "https://w3id.org/security#proofPurpose", 52 | :type :vocab, 53 | :context 54 | {:type-key "type", 55 | :version 1.1, 56 | :protected true, 57 | "id" {:id "@id"}, 58 | "type" {:id "@type", :type? true}, 59 | "sec" {:id "https://w3id.org/security#"}, 60 | "assertionMethod" 61 | {:id "https://w3id.org/security#assertionMethod", 62 | :type :id, 63 | :container :set}, 64 | "authentication" 65 | {:id "https://w3id.org/security#authenticationMethod", 66 | :type :id, 67 | :container :set}}}, 68 | "id" {:id "@id"}, 69 | "challenge" {:id "https://w3id.org/security#challenge"}, 70 | :type-key "type", 71 | "expires" 72 | {:id "https://w3id.org/security#expiration", 73 | :type "http://www.w3.org/2001/XMLSchema#dateTime"}, 74 | "domain" {:id "https://w3id.org/security#domain"}, 75 | "verificationMethod" 76 | {:id "https://w3id.org/security#verificationMethod", :type :id}, 77 | "proofValue" {:id "https://w3id.org/security#proofValue"}, 78 | "type" {:id "@type", :type? true}, 79 | :protected true, 80 | "nonce" {:id "https://w3id.org/security#nonce"}, 81 | :version 1.1, 82 | "sec" {:id "https://w3id.org/security#"}, 83 | "xsd" {:id "http://www.w3.org/2001/XMLSchema#"}}}, 84 | :type-key "type", 85 | "VerifiableCredential" 86 | {:id "https://www.w3.org/2018/credentials#VerifiableCredential", 87 | :context 88 | {"holder" 89 | {:id "https://www.w3.org/2018/credentials#holder", :type :id}, 90 | "credentialSubject" 91 | {:id "https://www.w3.org/2018/credentials#credentialSubject", 92 | :type :id}, 93 | "issuanceDate" 94 | {:id "https://www.w3.org/2018/credentials#issuanceDate", 95 | :type "http://www.w3.org/2001/XMLSchema#dateTime"}, 96 | "credentialStatus" 97 | {:id "https://www.w3.org/2018/credentials#credentialStatus", 98 | :type :id}, 99 | "validFrom" 100 | {:id "https://www.w3.org/2018/credentials#validFrom", 101 | :type "http://www.w3.org/2001/XMLSchema#dateTime"}, 102 | "issued" 103 | {:id "https://www.w3.org/2018/credentials#issued", 104 | :type "http://www.w3.org/2001/XMLSchema#dateTime"}, 105 | "issuer" 106 | {:id "https://www.w3.org/2018/credentials#issuer", :type :id}, 107 | "id" {:id "@id"}, 108 | :type-key "type", 109 | "proof" 110 | {:id "https://w3id.org/security#proof", 111 | :type :id, 112 | :container :graph}, 113 | "credentialSchema" 114 | {:id "https://www.w3.org/2018/credentials#credentialSchema", 115 | :type :id, 116 | :context 117 | {:type-key "type", 118 | :version 1.1, 119 | :protected true, 120 | "id" {:id "@id"}, 121 | "type" {:id "@type", :type? true}, 122 | "cred" {:id "https://www.w3.org/2018/credentials#"}, 123 | "JsonSchemaValidator2018" 124 | {:id 125 | "https://www.w3.org/2018/credentials#JsonSchemaValidator2018"}}}, 126 | "type" {:id "@type", :type? true}, 127 | "termsOfUse" 128 | {:id "https://www.w3.org/2018/credentials#termsOfUse", :type :id}, 129 | :protected true, 130 | "expirationDate" 131 | {:id "https://www.w3.org/2018/credentials#expirationDate", 132 | :type "http://www.w3.org/2001/XMLSchema#dateTime"}, 133 | "validUntil" 134 | {:id "https://www.w3.org/2018/credentials#validUntil", 135 | :type "http://www.w3.org/2001/XMLSchema#dateTime"}, 136 | :version 1.1, 137 | "cred" {:id "https://www.w3.org/2018/credentials#"}, 138 | "refreshService" 139 | {:id "https://www.w3.org/2018/credentials#refreshService", 140 | :type :id, 141 | :context 142 | {:type-key "type", 143 | :version 1.1, 144 | :protected true, 145 | "id" {:id "@id"}, 146 | "type" {:id "@type", :type? true}, 147 | "cred" {:id "https://www.w3.org/2018/credentials#"}, 148 | "ManualRefreshService2018" 149 | {:id 150 | "https://www.w3.org/2018/credentials#ManualRefreshService2018"}}}, 151 | "sec" {:id "https://w3id.org/security#"}, 152 | "evidence" 153 | {:id "https://www.w3.org/2018/credentials#evidence", :type :id}, 154 | "xsd" {:id "http://www.w3.org/2001/XMLSchema#"}}}, 155 | "proof" 156 | {:id "https://w3id.org/security#proof", :type :id, :container :graph}, 157 | "type" {:id "@type", :type? true}, 158 | :protected true, 159 | "EcdsaSecp256r1Signature2019" 160 | {:id "https://w3id.org/security#EcdsaSecp256r1Signature2019", 161 | :context 162 | {"created" 163 | {:id "http://purl.org/dc/terms/created", 164 | :type "http://www.w3.org/2001/XMLSchema#dateTime"}, 165 | "jws" {:id "https://w3id.org/security#jws"}, 166 | "proofPurpose" 167 | {:id "https://w3id.org/security#proofPurpose", 168 | :type :vocab, 169 | :context 170 | {:type-key "type", 171 | :version 1.1, 172 | :protected true, 173 | "id" {:id "@id"}, 174 | "type" {:id "@type", :type? true}, 175 | "sec" {:id "https://w3id.org/security#"}, 176 | "assertionMethod" 177 | {:id "https://w3id.org/security#assertionMethod", 178 | :type :id, 179 | :container :set}, 180 | "authentication" 181 | {:id "https://w3id.org/security#authenticationMethod", 182 | :type :id, 183 | :container :set}}}, 184 | "id" {:id "@id"}, 185 | "challenge" {:id "https://w3id.org/security#challenge"}, 186 | :type-key "type", 187 | "expires" 188 | {:id "https://w3id.org/security#expiration", 189 | :type "http://www.w3.org/2001/XMLSchema#dateTime"}, 190 | "domain" {:id "https://w3id.org/security#domain"}, 191 | "verificationMethod" 192 | {:id "https://w3id.org/security#verificationMethod", :type :id}, 193 | "proofValue" {:id "https://w3id.org/security#proofValue"}, 194 | "type" {:id "@type", :type? true}, 195 | :protected true, 196 | "nonce" {:id "https://w3id.org/security#nonce"}, 197 | :version 1.1, 198 | "sec" {:id "https://w3id.org/security#"}, 199 | "xsd" {:id "http://www.w3.org/2001/XMLSchema#"}}}, 200 | "VerifiablePresentation" 201 | {:id "https://www.w3.org/2018/credentials#VerifiablePresentation", 202 | :context 203 | {"holder" 204 | {:id "https://www.w3.org/2018/credentials#holder", :type :id}, 205 | "id" {:id "@id"}, 206 | "verifiableCredential" 207 | {:id "https://www.w3.org/2018/credentials#verifiableCredential", 208 | :type :id, 209 | :container :graph}, 210 | :type-key "type", 211 | "proof" 212 | {:id "https://w3id.org/security#proof", 213 | :type :id, 214 | :container :graph}, 215 | "type" {:id "@type", :type? true}, 216 | :protected true, 217 | :version 1.1, 218 | "cred" {:id "https://www.w3.org/2018/credentials#"}, 219 | "sec" {:id "https://w3id.org/security#"}}}, 220 | :version 1.1, 221 | "RsaSignature2018" 222 | {:id "https://w3id.org/security#RsaSignature2018", 223 | :context 224 | {"created" 225 | {:id "http://purl.org/dc/terms/created", :type "xsd:dateTime"}, 226 | "jws" {:id "sec:jws"}, 227 | "proofPurpose" 228 | {:id "sec:proofPurpose", 229 | :type :vocab, 230 | :context 231 | {:type-key "type", 232 | :version 1.1, 233 | :protected true, 234 | "id" {:id "@id"}, 235 | "type" {:id "@type", :type? true}, 236 | "sec" {:id "https://w3id.org/security#"}, 237 | "assertionMethod" 238 | {:id "https://w3id.org/security#assertionMethod", 239 | :type :id, 240 | :container :set}, 241 | "authentication" 242 | {:id "https://w3id.org/security#authenticationMethod", 243 | :type :id, 244 | :container :set}}}, 245 | "challenge" {:id "sec:challenge"}, 246 | :type-key "@type", 247 | "expires" {:id "sec:expiration", :type "xsd:dateTime"}, 248 | "domain" {:id "sec:domain"}, 249 | "verificationMethod" {:id "sec:verificationMethod", :type :id}, 250 | "proofValue" {:id "sec:proofValue"}, 251 | :protected true, 252 | "nonce" {:id "sec:nonce"}, 253 | :version 1.1}}} 254 | -------------------------------------------------------------------------------- /resources/contexts/org/w3/www/2018/credentials/v1.jsonld: -------------------------------------------------------------------------------- 1 | { 2 | "@context": { 3 | "@version": 1.1, 4 | "@protected": true, 5 | 6 | "id": "@id", 7 | "type": "@type", 8 | 9 | "VerifiableCredential": { 10 | "@id": "https://www.w3.org/2018/credentials#VerifiableCredential", 11 | "@context": { 12 | "@version": 1.1, 13 | "@protected": true, 14 | 15 | "id": "@id", 16 | "type": "@type", 17 | 18 | "cred": "https://www.w3.org/2018/credentials#", 19 | "sec": "https://w3id.org/security#", 20 | "xsd": "http://www.w3.org/2001/XMLSchema#", 21 | 22 | "credentialSchema": { 23 | "@id": "cred:credentialSchema", 24 | "@type": "@id", 25 | "@context": { 26 | "@version": 1.1, 27 | "@protected": true, 28 | 29 | "id": "@id", 30 | "type": "@type", 31 | 32 | "cred": "https://www.w3.org/2018/credentials#", 33 | 34 | "JsonSchemaValidator2018": "cred:JsonSchemaValidator2018" 35 | } 36 | }, 37 | "credentialStatus": {"@id": "cred:credentialStatus", "@type": "@id"}, 38 | "credentialSubject": {"@id": "cred:credentialSubject", "@type": "@id"}, 39 | "evidence": {"@id": "cred:evidence", "@type": "@id"}, 40 | "expirationDate": {"@id": "cred:expirationDate", "@type": "xsd:dateTime"}, 41 | "holder": {"@id": "cred:holder", "@type": "@id"}, 42 | "issued": {"@id": "cred:issued", "@type": "xsd:dateTime"}, 43 | "issuer": {"@id": "cred:issuer", "@type": "@id"}, 44 | "issuanceDate": {"@id": "cred:issuanceDate", "@type": "xsd:dateTime"}, 45 | "proof": {"@id": "sec:proof", "@type": "@id", "@container": "@graph"}, 46 | "refreshService": { 47 | "@id": "cred:refreshService", 48 | "@type": "@id", 49 | "@context": { 50 | "@version": 1.1, 51 | "@protected": true, 52 | 53 | "id": "@id", 54 | "type": "@type", 55 | 56 | "cred": "https://www.w3.org/2018/credentials#", 57 | 58 | "ManualRefreshService2018": "cred:ManualRefreshService2018" 59 | } 60 | }, 61 | "termsOfUse": {"@id": "cred:termsOfUse", "@type": "@id"}, 62 | "validFrom": {"@id": "cred:validFrom", "@type": "xsd:dateTime"}, 63 | "validUntil": {"@id": "cred:validUntil", "@type": "xsd:dateTime"} 64 | } 65 | }, 66 | 67 | "VerifiablePresentation": { 68 | "@id": "https://www.w3.org/2018/credentials#VerifiablePresentation", 69 | "@context": { 70 | "@version": 1.1, 71 | "@protected": true, 72 | 73 | "id": "@id", 74 | "type": "@type", 75 | 76 | "cred": "https://www.w3.org/2018/credentials#", 77 | "sec": "https://w3id.org/security#", 78 | 79 | "holder": {"@id": "cred:holder", "@type": "@id"}, 80 | "proof": {"@id": "sec:proof", "@type": "@id", "@container": "@graph"}, 81 | "verifiableCredential": {"@id": "cred:verifiableCredential", "@type": "@id", "@container": "@graph"} 82 | } 83 | }, 84 | 85 | "EcdsaSecp256k1Signature2019": { 86 | "@id": "https://w3id.org/security#EcdsaSecp256k1Signature2019", 87 | "@context": { 88 | "@version": 1.1, 89 | "@protected": true, 90 | 91 | "id": "@id", 92 | "type": "@type", 93 | 94 | "sec": "https://w3id.org/security#", 95 | "xsd": "http://www.w3.org/2001/XMLSchema#", 96 | 97 | "challenge": "sec:challenge", 98 | "created": {"@id": "http://purl.org/dc/terms/created", "@type": "xsd:dateTime"}, 99 | "domain": "sec:domain", 100 | "expires": {"@id": "sec:expiration", "@type": "xsd:dateTime"}, 101 | "jws": "sec:jws", 102 | "nonce": "sec:nonce", 103 | "proofPurpose": { 104 | "@id": "sec:proofPurpose", 105 | "@type": "@vocab", 106 | "@context": { 107 | "@version": 1.1, 108 | "@protected": true, 109 | 110 | "id": "@id", 111 | "type": "@type", 112 | 113 | "sec": "https://w3id.org/security#", 114 | 115 | "assertionMethod": {"@id": "sec:assertionMethod", "@type": "@id", "@container": "@set"}, 116 | "authentication": {"@id": "sec:authenticationMethod", "@type": "@id", "@container": "@set"} 117 | } 118 | }, 119 | "proofValue": "sec:proofValue", 120 | "verificationMethod": {"@id": "sec:verificationMethod", "@type": "@id"} 121 | } 122 | }, 123 | 124 | "EcdsaSecp256r1Signature2019": { 125 | "@id": "https://w3id.org/security#EcdsaSecp256r1Signature2019", 126 | "@context": { 127 | "@version": 1.1, 128 | "@protected": true, 129 | 130 | "id": "@id", 131 | "type": "@type", 132 | 133 | "sec": "https://w3id.org/security#", 134 | "xsd": "http://www.w3.org/2001/XMLSchema#", 135 | 136 | "challenge": "sec:challenge", 137 | "created": {"@id": "http://purl.org/dc/terms/created", "@type": "xsd:dateTime"}, 138 | "domain": "sec:domain", 139 | "expires": {"@id": "sec:expiration", "@type": "xsd:dateTime"}, 140 | "jws": "sec:jws", 141 | "nonce": "sec:nonce", 142 | "proofPurpose": { 143 | "@id": "sec:proofPurpose", 144 | "@type": "@vocab", 145 | "@context": { 146 | "@version": 1.1, 147 | "@protected": true, 148 | 149 | "id": "@id", 150 | "type": "@type", 151 | 152 | "sec": "https://w3id.org/security#", 153 | 154 | "assertionMethod": {"@id": "sec:assertionMethod", "@type": "@id", "@container": "@set"}, 155 | "authentication": {"@id": "sec:authenticationMethod", "@type": "@id", "@container": "@set"} 156 | } 157 | }, 158 | "proofValue": "sec:proofValue", 159 | "verificationMethod": {"@id": "sec:verificationMethod", "@type": "@id"} 160 | } 161 | }, 162 | 163 | "Ed25519Signature2018": { 164 | "@id": "https://w3id.org/security#Ed25519Signature2018", 165 | "@context": { 166 | "@version": 1.1, 167 | "@protected": true, 168 | 169 | "id": "@id", 170 | "type": "@type", 171 | 172 | "sec": "https://w3id.org/security#", 173 | "xsd": "http://www.w3.org/2001/XMLSchema#", 174 | 175 | "challenge": "sec:challenge", 176 | "created": {"@id": "http://purl.org/dc/terms/created", "@type": "xsd:dateTime"}, 177 | "domain": "sec:domain", 178 | "expires": {"@id": "sec:expiration", "@type": "xsd:dateTime"}, 179 | "jws": "sec:jws", 180 | "nonce": "sec:nonce", 181 | "proofPurpose": { 182 | "@id": "sec:proofPurpose", 183 | "@type": "@vocab", 184 | "@context": { 185 | "@version": 1.1, 186 | "@protected": true, 187 | 188 | "id": "@id", 189 | "type": "@type", 190 | 191 | "sec": "https://w3id.org/security#", 192 | 193 | "assertionMethod": {"@id": "sec:assertionMethod", "@type": "@id", "@container": "@set"}, 194 | "authentication": {"@id": "sec:authenticationMethod", "@type": "@id", "@container": "@set"} 195 | } 196 | }, 197 | "proofValue": "sec:proofValue", 198 | "verificationMethod": {"@id": "sec:verificationMethod", "@type": "@id"} 199 | } 200 | }, 201 | 202 | "RsaSignature2018": { 203 | "@id": "https://w3id.org/security#RsaSignature2018", 204 | "@context": { 205 | "@version": 1.1, 206 | "@protected": true, 207 | 208 | "challenge": "sec:challenge", 209 | "created": {"@id": "http://purl.org/dc/terms/created", "@type": "xsd:dateTime"}, 210 | "domain": "sec:domain", 211 | "expires": {"@id": "sec:expiration", "@type": "xsd:dateTime"}, 212 | "jws": "sec:jws", 213 | "nonce": "sec:nonce", 214 | "proofPurpose": { 215 | "@id": "sec:proofPurpose", 216 | "@type": "@vocab", 217 | "@context": { 218 | "@version": 1.1, 219 | "@protected": true, 220 | 221 | "id": "@id", 222 | "type": "@type", 223 | 224 | "sec": "https://w3id.org/security#", 225 | 226 | "assertionMethod": {"@id": "sec:assertionMethod", "@type": "@id", "@container": "@set"}, 227 | "authentication": {"@id": "sec:authenticationMethod", "@type": "@id", "@container": "@set"} 228 | } 229 | }, 230 | "proofValue": "sec:proofValue", 231 | "verificationMethod": {"@id": "sec:verificationMethod", "@type": "@id"} 232 | } 233 | }, 234 | 235 | "proof": {"@id": "https://w3id.org/security#proof", "@type": "@id", "@container": "@graph"} 236 | } 237 | } -------------------------------------------------------------------------------- /resources/contexts/org/w3/www/ns/did/v1.edn: -------------------------------------------------------------------------------- 1 | {"keyAgreement" 2 | {:id "https://w3id.org/security#keyAgreementMethod", 3 | :type :id, 4 | :container :set}, 5 | "authentication" 6 | {:id "https://w3id.org/security#authenticationMethod", 7 | :type :id, 8 | :container :set}, 9 | "assertionMethod" 10 | {:id "https://w3id.org/security#assertionMethod", 11 | :type :id, 12 | :container :set}, 13 | "id" {:id "@id"}, 14 | :type-key "type", 15 | "alsoKnownAs" 16 | {:id "https://www.w3.org/ns/activitystreams#alsoKnownAs", :type :id}, 17 | "verificationMethod" 18 | {:id "https://w3id.org/security#verificationMethod", :type :id}, 19 | "type" {:id "@type", :type? true}, 20 | :protected true, 21 | "service" 22 | {:id "https://www.w3.org/ns/did#service", 23 | :type :id, 24 | :context 25 | {:type-key "type", 26 | :protected true, 27 | "id" {:id "@id"}, 28 | "type" {:id "@type", :type? true}, 29 | "serviceEndpoint" 30 | {:id "https://www.w3.org/ns/did#serviceEndpoint", :type :id}}}, 31 | "capabilityInvocation" 32 | {:id "https://w3id.org/security#capabilityInvocationMethod", 33 | :type :id, 34 | :container :set}, 35 | "controller" {:id "https://w3id.org/security#controller", :type :id}, 36 | "capabilityDelegation" 37 | {:id "https://w3id.org/security#capabilityDelegationMethod", 38 | :type :id, 39 | :container :set}} 40 | -------------------------------------------------------------------------------- /resources/contexts/org/w3/www/ns/did/v1.jsonld: -------------------------------------------------------------------------------- 1 | { 2 | "@context": { 3 | "@protected": true, 4 | "id": "@id", 5 | "type": "@type", 6 | 7 | "alsoKnownAs": { 8 | "@id": "https://www.w3.org/ns/activitystreams#alsoKnownAs", 9 | "@type": "@id" 10 | }, 11 | "assertionMethod": { 12 | "@id": "https://w3id.org/security#assertionMethod", 13 | "@type": "@id", 14 | "@container": "@set" 15 | }, 16 | "authentication": { 17 | "@id": "https://w3id.org/security#authenticationMethod", 18 | "@type": "@id", 19 | "@container": "@set" 20 | }, 21 | "capabilityDelegation": { 22 | "@id": "https://w3id.org/security#capabilityDelegationMethod", 23 | "@type": "@id", 24 | "@container": "@set" 25 | }, 26 | "capabilityInvocation": { 27 | "@id": "https://w3id.org/security#capabilityInvocationMethod", 28 | "@type": "@id", 29 | "@container": "@set" 30 | }, 31 | "controller": { 32 | "@id": "https://w3id.org/security#controller", 33 | "@type": "@id" 34 | }, 35 | "keyAgreement": { 36 | "@id": "https://w3id.org/security#keyAgreementMethod", 37 | "@type": "@id", 38 | "@container": "@set" 39 | }, 40 | "service": { 41 | "@id": "https://www.w3.org/ns/did#service", 42 | "@type": "@id", 43 | "@context": { 44 | "@protected": true, 45 | "id": "@id", 46 | "type": "@type", 47 | "serviceEndpoint": { 48 | "@id": "https://www.w3.org/ns/did#serviceEndpoint", 49 | "@type": "@id" 50 | } 51 | } 52 | }, 53 | "verificationMethod": { 54 | "@id": "https://w3id.org/security#verificationMethod", 55 | "@type": "@id" 56 | } 57 | } 58 | } -------------------------------------------------------------------------------- /resources/contexts/org/w3/www/ns/shacl/v1.edn: -------------------------------------------------------------------------------- 1 | {"zeroOrMorePath" 2 | {:type :id, :id "http://www.w3.org/ns/shacl#zeroOrMorePath"}, 3 | "sourceConstraintComponent" 4 | {:type :id, 5 | :id "http://www.w3.org/ns/shacl#sourceConstraintComponent"}, 6 | "sparql" {:type :id, :id "http://www.w3.org/ns/shacl#sparql"}, 7 | "resultAnnotation" 8 | {:type :id, :id "http://www.w3.org/ns/shacl#resultAnnotation"}, 9 | "targetClass" 10 | {:type :id, :id "http://www.w3.org/ns/shacl#targetClass"}, 11 | "parameter" {:type :id, :id "http://www.w3.org/ns/shacl#parameter"}, 12 | "prefixes" {:type :id, :id "http://www.w3.org/ns/shacl#prefixes"}, 13 | "declare" {:type :id, :id "http://www.w3.org/ns/shacl#declare"}, 14 | "resultSeverity" 15 | {:type :id, :id "http://www.w3.org/ns/shacl#resultSeverity"}, 16 | "not" {:type :id, :id "http://www.w3.org/ns/shacl#not"}, 17 | "minLength" 18 | {:type "http://www.w3.org/2001/XMLSchema#integer", 19 | :id "http://www.w3.org/ns/shacl#minLength"}, 20 | "languageIn" 21 | {:container :list, :id "http://www.w3.org/ns/shacl#languageIn"}, 22 | "group" {:type :id, :id "http://www.w3.org/ns/shacl#group"}, 23 | "class" {:type :id, :id "http://www.w3.org/ns/shacl#class"}, 24 | "maxCount" 25 | {:type "http://www.w3.org/2001/XMLSchema#integer", 26 | :id "http://www.w3.org/ns/shacl#maxCount"}, 27 | "zeroOrOnePath" 28 | {:type :id, :id "http://www.w3.org/ns/shacl#zeroOrOnePath"}, 29 | "rdf" {:id "http://www.w3.org/1999/02/22-rdf-syntax-ns#"}, 30 | "minCount" 31 | {:type "http://www.w3.org/2001/XMLSchema#integer", 32 | :id "http://www.w3.org/ns/shacl#minCount"}, 33 | "derivedValues" 34 | {:type :id, :id "http://www.w3.org/ns/shacl#derivedValues"}, 35 | "alternativePath" 36 | {:type :id, 37 | :container :list, 38 | :id "http://www.w3.org/ns/shacl#alternativePath"}, 39 | "returnType" {:type :id, :id "http://www.w3.org/ns/shacl#returnType"}, 40 | "targetSubjectsOf" 41 | {:type :id, :id "http://www.w3.org/ns/shacl#targetSubjectsOf"}, 42 | "detail" {:type :id, :id "http://www.w3.org/ns/shacl#detail"}, 43 | "path" {:type :id, :id "http://www.w3.org/ns/shacl#path"}, 44 | "targetObjectsOf" 45 | {:type :id, :id "http://www.w3.org/ns/shacl#targetObjectsOf"}, 46 | "nodeKind" {:type :id, :id "http://www.w3.org/ns/shacl#nodeKind"}, 47 | "maxLength" 48 | {:type "http://www.w3.org/2001/XMLSchema#integer", 49 | :id "http://www.w3.org/ns/shacl#maxLength"}, 50 | :type-key "@type", 51 | "lessThanOrEquals" 52 | {:type :id, :id "http://www.w3.org/ns/shacl#lessThanOrEquals"}, 53 | "or" 54 | {:type :id, :container :list, :id "http://www.w3.org/ns/shacl#or"}, 55 | :vocab "http://www.w3.org/ns/shacl#", 56 | "resultPath" {:type :id, :id "http://www.w3.org/ns/shacl#resultPath"}, 57 | "propertyValidator" 58 | {:type :id, :id "http://www.w3.org/ns/shacl#propertyValidator"}, 59 | "property" {:type :id, :id "http://www.w3.org/ns/shacl#property"}, 60 | "disjoint" {:type :id, :id "http://www.w3.org/ns/shacl#disjoint"}, 61 | "lessThan" {:type :id, :id "http://www.w3.org/ns/shacl#lessThan"}, 62 | "rdfs" {:id "http://www.w3.org/2000/01/rdf-schema#"}, 63 | "and" 64 | {:type :id, :container :list, :id "http://www.w3.org/ns/shacl#and"}, 65 | "validator" {:type :id, :id "http://www.w3.org/ns/shacl#validator"}, 66 | "inversePath" 67 | {:type :id, :id "http://www.w3.org/ns/shacl#inversePath"}, 68 | "target" {:type :id, :id "http://www.w3.org/ns/shacl#target"}, 69 | "datatype" {:type :id, :id "http://www.w3.org/ns/shacl#datatype"}, 70 | "annotationProperty" 71 | {:type :id, :id "http://www.w3.org/ns/shacl#annotationProperty"}, 72 | "qualifiedValueShape" 73 | {:type :id, :id "http://www.w3.org/ns/shacl#qualifiedValueShape"}, 74 | "sh" {:id "http://www.w3.org/ns/shacl#"}, 75 | "sourceShape" 76 | {:type :id, :id "http://www.w3.org/ns/shacl#sourceShape"}, 77 | "qualifiedMinCount" 78 | {:type "http://www.w3.org/2001/XMLSchema#integer", 79 | :id "http://www.w3.org/ns/shacl#qualifiedMinCount"}, 80 | "namespace" 81 | {:type "http://www.w3.org/2001/XMLSchema#anyURI", 82 | :id "http://www.w3.org/ns/shacl#namespace"}, 83 | "comment" {:id "http://www.w3.org/2000/01/rdf-schema#comment"}, 84 | "ignoredProperties" 85 | {:type :id, 86 | :container :list, 87 | :id "http://www.w3.org/ns/shacl#ignoredProperties"}, 88 | "nodeValidator" 89 | {:type :id, :id "http://www.w3.org/ns/shacl#nodeValidator"}, 90 | "severity" {:type :id, :id "http://www.w3.org/ns/shacl#severity"}, 91 | "oneOrMorePath" 92 | {:type :id, :id "http://www.w3.org/ns/shacl#oneOrMorePath"}, 93 | "equals" {:type :id, :id "http://www.w3.org/ns/shacl#equals"}, 94 | "shapesGraph" 95 | {:type :id, :id "http://www.w3.org/ns/shacl#shapesGraph"}, 96 | "qualifiedMaxCount" 97 | {:type "http://www.w3.org/2001/XMLSchema#integer", 98 | :id "http://www.w3.org/ns/shacl#qualifiedMaxCount"}, 99 | "node" {:type :id, :id "http://www.w3.org/ns/shacl#node"}, 100 | "result" {:type :id, :id "http://www.w3.org/ns/shacl#result"}, 101 | "xsd" {:id "http://www.w3.org/2001/XMLSchema#"}, 102 | "in" {:container :list, :id "http://www.w3.org/ns/shacl#in"}, 103 | "xone" 104 | {:type :id, :container :list, :id "http://www.w3.org/ns/shacl#xone"}} 105 | -------------------------------------------------------------------------------- /resources/contexts/org/w3/www/ns/shacl/v1.jsonld: -------------------------------------------------------------------------------- 1 | { 2 | "@context": { 3 | "@vocab": "http://www.w3.org/ns/shacl#", 4 | "sh" : "http://www.w3.org/ns/shacl#", 5 | "rdf": "http://www.w3.org/1999/02/22-rdf-syntax-ns#", 6 | "rdfs" : "http://www.w3.org/2000/01/rdf-schema#", 7 | "xsd": "http://www.w3.org/2001/XMLSchema#", 8 | "comment": "rdfs:comment", 9 | "target" : { 10 | "@type" : "@id" 11 | }, 12 | "targetClass" : { 13 | "@type" : "@id" 14 | }, 15 | "targetObjectsOf" : { 16 | "@type" : "@id" 17 | }, 18 | "targetSubjectsOf" : { 19 | "@type" : "@id" 20 | }, 21 | "severity" : { 22 | "@type" : "@id" 23 | }, 24 | "result" : { 25 | "@type" : "@id" 26 | }, 27 | "detail" : { 28 | "@type" : "@id" 29 | }, 30 | "resultPath" : { 31 | "@type" : "@id" 32 | }, 33 | "resultSeverity" : { 34 | "@type" : "@id" 35 | }, 36 | "sourceShape" : { 37 | "@type" : "@id" 38 | }, 39 | "sourceConstraintComponent" : { 40 | "@type" : "@id" 41 | }, 42 | "prefixes" : { 43 | "@type" : "@id" 44 | }, 45 | "declare" : { 46 | "@type" : "@id" 47 | }, 48 | "namespace" : { 49 | "@type" : "xsd:anyURI" 50 | }, 51 | "shapesGraph" : { 52 | "@type" : "@id" 53 | }, 54 | "path" : { 55 | "@type" : "@id" 56 | }, 57 | "inversePath" : { 58 | "@type" : "@id" 59 | }, 60 | "alternativePath" : { 61 | "@type" : "@id", 62 | "@container" : "@list" 63 | }, 64 | "zeroOrMorePath" : { 65 | "@type" : "@id" 66 | }, 67 | "oneOrMorePath" : { 68 | "@type" : "@id" 69 | }, 70 | "zeroOrOnePath" : { 71 | "@type" : "@id" 72 | }, 73 | "parameter" : { 74 | "@type" : "@id" 75 | }, 76 | "validator" : { 77 | "@type" : "@id" 78 | }, 79 | "nodeValidator" : { 80 | "@type" : "@id" 81 | }, 82 | "propertyValidator" : { 83 | "@type" : "@id" 84 | }, 85 | "and" : { 86 | "@type" : "@id", 87 | "@container" : "@list" 88 | }, 89 | "class" : { 90 | "@type" : "@id" 91 | }, 92 | "ignoredProperties" : { 93 | "@type" : "@id", 94 | "@container" : "@list" 95 | }, 96 | "datatype" : { 97 | "@type" : "@id" 98 | }, 99 | "disjoint" : { 100 | "@type" : "@id" 101 | }, 102 | "equals" : { 103 | "@type" : "@id" 104 | }, 105 | "in" : { 106 | "@container" : "@list" 107 | }, 108 | "languageIn" : { 109 | "@container" : "@list" 110 | }, 111 | "lessThan" : { 112 | "@type" : "@id" 113 | }, 114 | "lessThanOrEquals" : { 115 | "@type" : "@id" 116 | }, 117 | "node" : { 118 | "@type" : "@id" 119 | }, 120 | "nodeKind" : { 121 | "@type" : "@id" 122 | }, 123 | "not" : { 124 | "@type" : "@id" 125 | }, 126 | "or" : { 127 | "@type" : "@id", 128 | "@container" : "@list" 129 | }, 130 | "property" : { 131 | "@type" : "@id" 132 | }, 133 | "qualifiedValueShape" : { 134 | "@type" : "@id" 135 | }, 136 | "xone" : { 137 | "@type" : "@id", 138 | "@container" : "@list" 139 | }, 140 | "sparql" : { 141 | "@type" : "@id" 142 | }, 143 | "derivedValues" : { 144 | "@type" : "@id" 145 | }, 146 | "group" : { 147 | "@type" : "@id" 148 | }, 149 | "returnType" : { 150 | "@type" : "@id" 151 | }, 152 | "resultAnnotation" : { 153 | "@type" : "@id" 154 | }, 155 | "annotationProperty" : { 156 | "@type" : "@id" 157 | }, 158 | "maxCount" : { 159 | "@type" : "xsd:integer" 160 | }, 161 | "maxLength" : { 162 | "@type" : "xsd:integer" 163 | }, 164 | "minCount" : { 165 | "@type" : "xsd:integer" 166 | }, 167 | "minLength" : { 168 | "@type" : "xsd:integer" 169 | }, 170 | "qualifiedMaxCount" : { 171 | "@type" : "xsd:integer" 172 | }, 173 | "qualifiedMinCount" : { 174 | "@type" : "xsd:integer" 175 | } 176 | } 177 | } -------------------------------------------------------------------------------- /resources/contexts/org/w3id/security/v1.edn: -------------------------------------------------------------------------------- 1 | {"EncryptedMessage" {:id "https://w3id.org/security#EncryptedMessage"}, 2 | "dc" {:id "http://purl.org/dc/terms/"}, 3 | "canonicalizationAlgorithm" 4 | {:id "https://w3id.org/security#canonicalizationAlgorithm"}, 5 | "owner" {:id "https://w3id.org/security#owner", :type :id}, 6 | "created" 7 | {:id "http://purl.org/dc/terms/created", 8 | :type "http://www.w3.org/2001/XMLSchema#dateTime"}, 9 | "signatureValue" {:id "https://w3id.org/security#signatureValue"}, 10 | "CryptographicKey" {:id "https://w3id.org/security#Key"}, 11 | "publicKeyPem" {:id "https://w3id.org/security#publicKeyPem"}, 12 | "iterationCount" {:id "https://w3id.org/security#iterationCount"}, 13 | "id" {:id "@id"}, 14 | "publicKey" {:id "https://w3id.org/security#publicKey", :type :id}, 15 | "Ed25519Signature2018" 16 | {:id "https://w3id.org/security#Ed25519Signature2018"}, 17 | "publicKeyWif" {:id "https://w3id.org/security#publicKeyWif"}, 18 | "GraphSignature2012" 19 | {:id "https://w3id.org/security#GraphSignature2012"}, 20 | "creator" {:id "http://purl.org/dc/terms/creator", :type :id}, 21 | :type-key "type", 22 | "publicKeyBase58" {:id "https://w3id.org/security#publicKeyBase58"}, 23 | "cipherAlgorithm" {:id "https://w3id.org/security#cipherAlgorithm"}, 24 | "digestAlgorithm" {:id "https://w3id.org/security#digestAlgorithm"}, 25 | "LinkedDataSignature2015" 26 | {:id "https://w3id.org/security#LinkedDataSignature2015"}, 27 | "cipherData" {:id "https://w3id.org/security#cipherData"}, 28 | "privateKey" {:id "https://w3id.org/security#privateKey", :type :id}, 29 | "EcdsaKoblitzSignature2016" 30 | {:id "https://w3id.org/security#EcdsaKoblitzSignature2016"}, 31 | "expires" 32 | {:id "https://w3id.org/security#expiration", 33 | :type "http://www.w3.org/2001/XMLSchema#dateTime"}, 34 | "signatureAlgorithm" 35 | {:id "https://w3id.org/security#signingAlgorithm"}, 36 | "signature" {:id "https://w3id.org/security#signature"}, 37 | "domain" {:id "https://w3id.org/security#domain"}, 38 | "LinkedDataSignature2016" 39 | {:id "https://w3id.org/security#LinkedDataSignature2016"}, 40 | "revoked" 41 | {:id "https://w3id.org/security#revoked", 42 | :type "http://www.w3.org/2001/XMLSchema#dateTime"}, 43 | "encryptionKey" {:id "https://w3id.org/security#encryptionKey"}, 44 | "cipherKey" {:id "https://w3id.org/security#cipherKey"}, 45 | "salt" {:id "https://w3id.org/security#salt"}, 46 | "digestValue" {:id "https://w3id.org/security#digestValue"}, 47 | "type" {:id "@type", :type? true}, 48 | "password" {:id "https://w3id.org/security#password"}, 49 | "expiration" 50 | {:id "https://w3id.org/security#expiration", 51 | :type "http://www.w3.org/2001/XMLSchema#dateTime"}, 52 | "publicKeyService" 53 | {:id "https://w3id.org/security#publicKeyService", :type :id}, 54 | "nonce" {:id "https://w3id.org/security#nonce"}, 55 | "authenticationTag" 56 | {:id "https://w3id.org/security#authenticationTag"}, 57 | "privateKeyPem" {:id "https://w3id.org/security#privateKeyPem"}, 58 | "sec" {:id "https://w3id.org/security#"}, 59 | "normalizationAlgorithm" 60 | {:id "https://w3id.org/security#normalizationAlgorithm"}, 61 | "initializationVector" 62 | {:id "https://w3id.org/security#initializationVector"}, 63 | "xsd" {:id "http://www.w3.org/2001/XMLSchema#"}} 64 | -------------------------------------------------------------------------------- /resources/contexts/org/w3id/security/v1.jsonld: -------------------------------------------------------------------------------- 1 | { 2 | "@context": { 3 | "id": "@id", 4 | "type": "@type", 5 | 6 | "dc": "http://purl.org/dc/terms/", 7 | "sec": "https://w3id.org/security#", 8 | "xsd": "http://www.w3.org/2001/XMLSchema#", 9 | 10 | "EcdsaKoblitzSignature2016": "sec:EcdsaKoblitzSignature2016", 11 | "Ed25519Signature2018": "sec:Ed25519Signature2018", 12 | "EncryptedMessage": "sec:EncryptedMessage", 13 | "GraphSignature2012": "sec:GraphSignature2012", 14 | "LinkedDataSignature2015": "sec:LinkedDataSignature2015", 15 | "LinkedDataSignature2016": "sec:LinkedDataSignature2016", 16 | "CryptographicKey": "sec:Key", 17 | 18 | "authenticationTag": "sec:authenticationTag", 19 | "canonicalizationAlgorithm": "sec:canonicalizationAlgorithm", 20 | "cipherAlgorithm": "sec:cipherAlgorithm", 21 | "cipherData": "sec:cipherData", 22 | "cipherKey": "sec:cipherKey", 23 | "created": {"@id": "dc:created", "@type": "xsd:dateTime"}, 24 | "creator": {"@id": "dc:creator", "@type": "@id"}, 25 | "digestAlgorithm": "sec:digestAlgorithm", 26 | "digestValue": "sec:digestValue", 27 | "domain": "sec:domain", 28 | "encryptionKey": "sec:encryptionKey", 29 | "expiration": {"@id": "sec:expiration", "@type": "xsd:dateTime"}, 30 | "expires": {"@id": "sec:expiration", "@type": "xsd:dateTime"}, 31 | "initializationVector": "sec:initializationVector", 32 | "iterationCount": "sec:iterationCount", 33 | "nonce": "sec:nonce", 34 | "normalizationAlgorithm": "sec:normalizationAlgorithm", 35 | "owner": {"@id": "sec:owner", "@type": "@id"}, 36 | "password": "sec:password", 37 | "privateKey": {"@id": "sec:privateKey", "@type": "@id"}, 38 | "privateKeyPem": "sec:privateKeyPem", 39 | "publicKey": {"@id": "sec:publicKey", "@type": "@id"}, 40 | "publicKeyBase58": "sec:publicKeyBase58", 41 | "publicKeyPem": "sec:publicKeyPem", 42 | "publicKeyWif": "sec:publicKeyWif", 43 | "publicKeyService": {"@id": "sec:publicKeyService", "@type": "@id"}, 44 | "revoked": {"@id": "sec:revoked", "@type": "xsd:dateTime"}, 45 | "salt": "sec:salt", 46 | "signature": "sec:signature", 47 | "signatureAlgorithm": "sec:signingAlgorithm", 48 | "signatureValue": "sec:signatureValue" 49 | } 50 | } -------------------------------------------------------------------------------- /resources/contexts/org/w3id/security/v2.edn: -------------------------------------------------------------------------------- 1 | {"RsaVerificationKey2018" 2 | {:id "https://w3id.org/security#RsaVerificationKey2018"}, 3 | "EncryptedMessage" {:id "https://w3id.org/security#EncryptedMessage"}, 4 | "dc" {:id "http://purl.org/dc/terms/"}, 5 | "capabilityChain" 6 | {:id "https://w3id.org/security#capabilityChain", 7 | :type :id, 8 | :container :list}, 9 | "canonicalizationAlgorithm" 10 | {:id "https://w3id.org/security#canonicalizationAlgorithm"}, 11 | "keyAgreement" 12 | {:id "https://w3id.org/security#keyAgreementMethod", 13 | :type :id, 14 | :container :set}, 15 | "ciphertext" {:id "https://w3id.org/security#ciphertext"}, 16 | "caveat" 17 | {:id "https://w3id.org/security#caveat", :type :id, :container :set}, 18 | "owner" {:id "https://w3id.org/security#owner", :type :id}, 19 | "created" 20 | {:id "http://purl.org/dc/terms/created", 21 | :type "http://www.w3.org/2001/XMLSchema#dateTime"}, 22 | "signatureValue" {:id "https://w3id.org/security#signatureValue"}, 23 | "CryptographicKey" {:id "https://w3id.org/security#Key"}, 24 | "AesKeyWrappingKey2019" 25 | {:id "https://w3id.org/security#AesKeyWrappingKey2019"}, 26 | "authentication" 27 | {:id "https://w3id.org/security#authenticationMethod", 28 | :type :id, 29 | :container :set}, 30 | "wrappedKey" {:id "https://w3id.org/security#wrappedKey"}, 31 | "EcdsaSecp256k1Signature2019" 32 | {:id "https://w3id.org/security#EcdsaSecp256k1Signature2019"}, 33 | "publicKeyPem" {:id "https://w3id.org/security#publicKeyPem"}, 34 | "invocationTarget" 35 | {:id "https://w3id.org/security#invocationTarget", :type :id}, 36 | "DeriveSecretOperation" 37 | {:id "https://w3id.org/security#DeriveSecretOperation"}, 38 | "iterationCount" {:id "https://w3id.org/security#iterationCount"}, 39 | "EcdsaSecp256r1VerificationKey2019" 40 | {:id "https://w3id.org/security#EcdsaSecp256r1VerificationKey2019"}, 41 | "jws" {:id "https://w3id.org/security#jws"}, 42 | "proofPurpose" 43 | {:id "https://w3id.org/security#proofPurpose", :type :vocab}, 44 | "assertionMethod" 45 | {:id "https://w3id.org/security#assertionMethod", 46 | :type :id, 47 | :container :set}, 48 | "EquihashProof2018" 49 | {:id "https://w3id.org/security#EquihashProof2018"}, 50 | "capability" {:id "https://w3id.org/security#capability", :type :id}, 51 | "parentCapability" 52 | {:id "https://w3id.org/security#parentCapability", :type :id}, 53 | "Ed25519VerificationKey2018" 54 | {:id "https://w3id.org/security#Ed25519VerificationKey2018"}, 55 | "id" {:id "@id"}, 56 | "publicKey" {:id "https://w3id.org/security#publicKey", :type :id}, 57 | "Ed25519Signature2018" 58 | {:id "https://w3id.org/security#Ed25519Signature2018"}, 59 | "RevokeKeyOperation" 60 | {:id "https://w3id.org/security#RevokeKeyOperation"}, 61 | "publicKeyWif" {:id "https://w3id.org/security#publicKeyWif"}, 62 | "equihashParameterN" 63 | {:id "https://w3id.org/security#equihashParameterN", 64 | :type "http://www.w3.org/2001/XMLSchema#integer"}, 65 | "GraphSignature2012" 66 | {:id "https://w3id.org/security#GraphSignature2012"}, 67 | "creator" {:id "http://purl.org/dc/terms/creator", :type :id}, 68 | "challenge" {:id "https://w3id.org/security#challenge"}, 69 | :type-key "type", 70 | "publicKeyBase58" {:id "https://w3id.org/security#publicKeyBase58"}, 71 | "unwrappedKey" {:id "https://w3id.org/security#unwrappedKey"}, 72 | "cipherAlgorithm" {:id "https://w3id.org/security#cipherAlgorithm"}, 73 | "digestAlgorithm" {:id "https://w3id.org/security#digestAlgorithm"}, 74 | "invoker" {:id "https://w3id.org/security#invoker", :type :id}, 75 | "LinkedDataSignature2015" 76 | {:id "https://w3id.org/security#LinkedDataSignature2015"}, 77 | "proof" 78 | {:id "https://w3id.org/security#proof", :type :id, :container :graph}, 79 | "cipherData" {:id "https://w3id.org/security#cipherData"}, 80 | "privateKey" {:id "https://w3id.org/security#privateKey", :type :id}, 81 | "equihashParameterK" 82 | {:id "https://w3id.org/security#equihashParameterK", 83 | :type "http://www.w3.org/2001/XMLSchema#integer"}, 84 | "EcdsaKoblitzSignature2016" 85 | {:id "https://w3id.org/security#EcdsaKoblitzSignature2016"}, 86 | "expires" 87 | {:id "https://w3id.org/security#expiration", 88 | :type "http://www.w3.org/2001/XMLSchema#dateTime"}, 89 | "signatureAlgorithm" 90 | {:id "https://w3id.org/security#signingAlgorithm"}, 91 | "verifyData" {:id "https://w3id.org/security#verifyData"}, 92 | "signature" {:id "https://w3id.org/security#signature"}, 93 | "domain" {:id "https://w3id.org/security#domain"}, 94 | "VerifyOperation" {:id "https://w3id.org/security#VerifyOperation"}, 95 | "LinkedDataSignature2016" 96 | {:id "https://w3id.org/security#LinkedDataSignature2016"}, 97 | "revoked" 98 | {:id "https://w3id.org/security#revoked", 99 | :type "http://www.w3.org/2001/XMLSchema#dateTime"}, 100 | "ExportKeyOperation" 101 | {:id "https://w3id.org/security#ExportKeyOperation"}, 102 | "Sha256HmacKey2019" 103 | {:id "https://w3id.org/security#Sha256HmacKey2019"}, 104 | "encryptionKey" {:id "https://w3id.org/security#encryptionKey"}, 105 | "cipherKey" {:id "https://w3id.org/security#cipherKey"}, 106 | "salt" {:id "https://w3id.org/security#salt"}, 107 | "digestValue" {:id "https://w3id.org/security#digestValue"}, 108 | "verificationMethod" 109 | {:id "https://w3id.org/security#verificationMethod", :type :id}, 110 | "SignOperation" {:id "https://w3id.org/security#SignOperation"}, 111 | "allowedAction" {:id "https://w3id.org/security#allowedAction"}, 112 | "proofValue" {:id "https://w3id.org/security#proofValue"}, 113 | "type" {:id "@type", :type? true}, 114 | "X25519KeyAgreementKey2019" 115 | {:id "https://w3id.org/security#X25519KeyAgreementKey2019"}, 116 | "plaintext" {:id "https://w3id.org/security#plaintext"}, 117 | "GenerateKeyOperation" 118 | {:id "https://w3id.org/security#GenerateKeyOperation"}, 119 | "EcdsaSecp256r1Signature2019" 120 | {:id "https://w3id.org/security#EcdsaSecp256r1Signature2019"}, 121 | "DeleteKeyOperation" 122 | {:id "https://w3id.org/security#DeleteKeyOperation"}, 123 | "password" {:id "https://w3id.org/security#password"}, 124 | "EcdsaSecp256k1VerificationKey2019" 125 | {:id "https://w3id.org/security#EcdsaSecp256k1VerificationKey2019"}, 126 | "expiration" 127 | {:id "https://w3id.org/security#expiration", 128 | :type "http://www.w3.org/2001/XMLSchema#dateTime"}, 129 | "publicKeyService" 130 | {:id "https://w3id.org/security#publicKeyService", :type :id}, 131 | "nonce" {:id "https://w3id.org/security#nonce"}, 132 | "authenticationTag" 133 | {:id "https://w3id.org/security#authenticationTag"}, 134 | "capabilityAction" {:id "https://w3id.org/security#capabilityAction"}, 135 | "privateKeyPem" {:id "https://w3id.org/security#privateKeyPem"}, 136 | :version 1.1, 137 | "capabilityInvocation" 138 | {:id "https://w3id.org/security#capabilityInvocationMethod", 139 | :type :id, 140 | :container :set}, 141 | "sec" {:id "https://w3id.org/security#"}, 142 | "WrapKeyOperation" {:id "https://w3id.org/security#WrapKeyOperation"}, 143 | "kmsModule" {:id "https://w3id.org/security#kmsModule"}, 144 | "delegator" {:id "https://w3id.org/security#delegator", :type :id}, 145 | "UnwrapKeyOperation" 146 | {:id "https://w3id.org/security#UnwrapKeyOperation"}, 147 | "normalizationAlgorithm" 148 | {:id "https://w3id.org/security#normalizationAlgorithm"}, 149 | "controller" {:id "https://w3id.org/security#controller", :type :id}, 150 | "initializationVector" 151 | {:id "https://w3id.org/security#initializationVector"}, 152 | "RsaSignature2018" {:id "https://w3id.org/security#RsaSignature2018"}, 153 | "capabilityDelegation" 154 | {:id "https://w3id.org/security#capabilityDelegationMethod", 155 | :type :id, 156 | :container :set}, 157 | "KmsOperation" {:id "https://w3id.org/security#KmsOperation"}, 158 | "xsd" {:id "http://www.w3.org/2001/XMLSchema#"}, 159 | "referenceId" {:id "https://w3id.org/security#referenceId"}} 160 | -------------------------------------------------------------------------------- /resources/contexts/org/w3id/security/v2.jsonld: -------------------------------------------------------------------------------- 1 | { 2 | "@context": [{ 3 | "@version": 1.1 4 | }, "https://w3id.org/security/v1", { 5 | "AesKeyWrappingKey2019": "sec:AesKeyWrappingKey2019", 6 | "DeleteKeyOperation": "sec:DeleteKeyOperation", 7 | "DeriveSecretOperation": "sec:DeriveSecretOperation", 8 | "EcdsaSecp256k1Signature2019": "sec:EcdsaSecp256k1Signature2019", 9 | "EcdsaSecp256r1Signature2019": "sec:EcdsaSecp256r1Signature2019", 10 | "EcdsaSecp256k1VerificationKey2019": "sec:EcdsaSecp256k1VerificationKey2019", 11 | "EcdsaSecp256r1VerificationKey2019": "sec:EcdsaSecp256r1VerificationKey2019", 12 | "Ed25519Signature2018": "sec:Ed25519Signature2018", 13 | "Ed25519VerificationKey2018": "sec:Ed25519VerificationKey2018", 14 | "EquihashProof2018": "sec:EquihashProof2018", 15 | "ExportKeyOperation": "sec:ExportKeyOperation", 16 | "GenerateKeyOperation": "sec:GenerateKeyOperation", 17 | "KmsOperation": "sec:KmsOperation", 18 | "RevokeKeyOperation": "sec:RevokeKeyOperation", 19 | "RsaSignature2018": "sec:RsaSignature2018", 20 | "RsaVerificationKey2018": "sec:RsaVerificationKey2018", 21 | "Sha256HmacKey2019": "sec:Sha256HmacKey2019", 22 | "SignOperation": "sec:SignOperation", 23 | "UnwrapKeyOperation": "sec:UnwrapKeyOperation", 24 | "VerifyOperation": "sec:VerifyOperation", 25 | "WrapKeyOperation": "sec:WrapKeyOperation", 26 | "X25519KeyAgreementKey2019": "sec:X25519KeyAgreementKey2019", 27 | 28 | "allowedAction": "sec:allowedAction", 29 | "assertionMethod": {"@id": "sec:assertionMethod", "@type": "@id", "@container": "@set"}, 30 | "authentication": {"@id": "sec:authenticationMethod", "@type": "@id", "@container": "@set"}, 31 | "capability": {"@id": "sec:capability", "@type": "@id"}, 32 | "capabilityAction": "sec:capabilityAction", 33 | "capabilityChain": {"@id": "sec:capabilityChain", "@type": "@id", "@container": "@list"}, 34 | "capabilityDelegation": {"@id": "sec:capabilityDelegationMethod", "@type": "@id", "@container": "@set"}, 35 | "capabilityInvocation": {"@id": "sec:capabilityInvocationMethod", "@type": "@id", "@container": "@set"}, 36 | "caveat": {"@id": "sec:caveat", "@type": "@id", "@container": "@set"}, 37 | "challenge": "sec:challenge", 38 | "ciphertext": "sec:ciphertext", 39 | "controller": {"@id": "sec:controller", "@type": "@id"}, 40 | "delegator": {"@id": "sec:delegator", "@type": "@id"}, 41 | "equihashParameterK": {"@id": "sec:equihashParameterK", "@type": "xsd:integer"}, 42 | "equihashParameterN": {"@id": "sec:equihashParameterN", "@type": "xsd:integer"}, 43 | "invocationTarget": {"@id": "sec:invocationTarget", "@type": "@id"}, 44 | "invoker": {"@id": "sec:invoker", "@type": "@id"}, 45 | "jws": "sec:jws", 46 | "keyAgreement": {"@id": "sec:keyAgreementMethod", "@type": "@id", "@container": "@set"}, 47 | "kmsModule": {"@id": "sec:kmsModule"}, 48 | "parentCapability": {"@id": "sec:parentCapability", "@type": "@id"}, 49 | "plaintext": "sec:plaintext", 50 | "proof": {"@id": "sec:proof", "@type": "@id", "@container": "@graph"}, 51 | "proofPurpose": {"@id": "sec:proofPurpose", "@type": "@vocab"}, 52 | "proofValue": "sec:proofValue", 53 | "referenceId": "sec:referenceId", 54 | "unwrappedKey": "sec:unwrappedKey", 55 | "verificationMethod": {"@id": "sec:verificationMethod", "@type": "@id"}, 56 | "verifyData": "sec:verifyData", 57 | "wrappedKey": "sec:wrappedKey" 58 | }] 59 | } -------------------------------------------------------------------------------- /resources/org.imsglobal.purl.spec.clr.v1p0.context.clr_v1p0.jsonld: -------------------------------------------------------------------------------- 1 | { 2 | "@context": { 3 | "id": "@id", 4 | "type": "@type", 5 | "clri": "https://purl.imsglobal.org/spec/clr/vocab#", 6 | "xsd": "http://www.w3.org/2001/XMLSchema#", 7 | "dtAchievement": "clri:dtAchievement", 8 | "dtAddress": "clri:dtAddress", 9 | "dtAlignment": "clri:dtAlignment", 10 | "dtArtifact": "clri:dtArtifact", 11 | "dtAssertion": "clri:dtAssertion", 12 | "dtAssociation": "clri:dtAssociation", 13 | "dtClr": "clri:dtClr", 14 | "dtCriteria": "clri:dtCriteria", 15 | "dtCryptographicKey": "clri:dtCryptographicKey", 16 | "dtEndorsement": "clri:dtEndorsement", 17 | "dtEndorsementClaim": "clri:dtEndorsementClaim", 18 | "dtEndorsementProfile": "clri:dtEndorsementProfile", 19 | "dtEvidence": "clri:dtEvidence", 20 | "dtExtensibleAchievementType": "clri:dtExtensibleAchievementType", 21 | "dtExtensibleAlignmentTargetType": "clri:dtExtensibleAlignmentTargetType", 22 | "dtExtensibleResultType": "clri:dtExtensibleResultType", 23 | "dtExtensibleSystemIdentifierType": "clri:dtExtensibleSystemIdentifierType", 24 | "dtIdentity": "clri:dtIdentity", 25 | "dtProfile": "clri:dtProfile", 26 | "dtResult": "clri:dtResult", 27 | "dtResultDescription": "clri:dtResultDescription", 28 | "dtRevocationList": "clri:dtRevocationList", 29 | "dtRubricCriterionLevel": "clri:dtRubricCriterionLevel", 30 | "dtSystemIdentifier": "clri:dtSystemIdentifier", 31 | "dtVerification": "clri:dtVerification", 32 | "dtCompactJws": { 33 | "@id": "clri:dtCompactJws", 34 | "@type": "xsd:string" 35 | }, 36 | "dtEnumExtString": { 37 | "@id": "clri:dtEnumExtString", 38 | "@type": "xsd:string" 39 | }, 40 | "dtIRI": { 41 | "@id": "clri:dtIRI", 42 | "@type": "xsd:normalizedString" 43 | }, 44 | "dtMarkdown": { 45 | "@id": "clri:dtMarkdown", 46 | "@type": "xsd:string" 47 | }, 48 | "dtUUID": { 49 | "@id": "clri:dtUUID", 50 | "@type": "xsd:string" 51 | }, 52 | "achievedLevel": "clri:dtIRI", 53 | "achievement": "clri:dtAchievement", 54 | "achievementType": "clri:dtExtensibleAchievementType", 55 | "achievements": { 56 | "@id": "clri:dtAchievement", 57 | "@container": "@set" 58 | }, 59 | "activityEndDate": { 60 | "@id": "clri:activityEndDate", 61 | "@type": "xsd:dateTime" 62 | }, 63 | "activityStartDate": { 64 | "@id": "clri:activityStartDate", 65 | "@type": "xsd:dateTime" 66 | }, 67 | "address": "clri:dtAddress", 68 | "addressCountry": { 69 | "@id": "clri:addressCountry", 70 | "@type": "xsd:string" 71 | }, 72 | "addressLocality": { 73 | "@id": "clri:addressLocality", 74 | "@type": "xsd:string" 75 | }, 76 | "addressRegion": { 77 | "@id": "clri:addressRegion", 78 | "@type": "xsd:string" 79 | }, 80 | "allowedValues": { 81 | "@id": "clri:allowedValues", 82 | "@type": "xsd:string", 83 | "@container": "@set" 84 | }, 85 | "artifacts": { 86 | "@id": "clri:dtArtifact", 87 | "@container": "@set" 88 | }, 89 | "assertions": { 90 | "@id": "clri:dtAssertion", 91 | "@container": "@set" 92 | }, 93 | "associationType": "clri:AssociationTypeDType", 94 | "associations": { 95 | "@id": "clri:dtAssociation", 96 | "@container": "@set" 97 | }, 98 | "birthDate": { 99 | "@id": "clri:birthDate", 100 | "@type": "xsd:date" 101 | }, 102 | "claim": "cred:claim", 103 | "clr": "clri:dtClr", 104 | "clrs": { 105 | "@id": "clri:dtClr", 106 | "@container": "@set" 107 | }, 108 | "creditsAvailable": { 109 | "@id": "clri:creditsAvailable", 110 | "@type": "xsd:float" 111 | }, 112 | "creditsEarned": { 113 | "@id": "clri:creditsEarned", 114 | "@type": "xsd:float" 115 | }, 116 | "endorsementComment": "obi:endorsementComment", 117 | "fieldOfStudy": { 118 | "@id": "clri:fieldOfStudy", 119 | "@type": "xsd:string" 120 | }, 121 | "humanCode": { 122 | "@id": "clri:humanCode", 123 | "@type": "xsd:string" 124 | }, 125 | "identifier": { 126 | "@id": "clri:identifier", 127 | "@type": "xsd:string" 128 | }, 129 | "identifierType": "clri:dtExtensibleSystemIdentifierType", 130 | "identifiers": { 131 | "@id": "clri:dtSystemIdentifier", 132 | "@container": "@set" 133 | }, 134 | "image": { 135 | "@id": "schema:image", 136 | "@type": "@id" 137 | }, 138 | "issuer": "obi:issuer", 139 | "learner": { 140 | "@id": "clri:learner", 141 | "@type": "@id" 142 | }, 143 | "level": { 144 | "@id": "clri:level", 145 | "@type": "xsd:string" 146 | }, 147 | "licenseNumber": { 148 | "@id": "clri:licenseNumber", 149 | "@type": "xsd:string" 150 | }, 151 | "narrative": "obi:narrative", 152 | "official": { 153 | "@id": "clri:official", 154 | "@type": "xsd:string" 155 | }, 156 | "owner": "sec:owner", 157 | "parentOrg": "obi:Profile", 158 | "partial": { 159 | "@id": "clri:partial", 160 | "@type": "xsd:boolean" 161 | }, 162 | "points": { 163 | "@id": "clri:points", 164 | "@type": "xsd:string" 165 | }, 166 | "postOfficeBoxNumber": { 167 | "@id": "clri:postOfficeBoxNumber", 168 | "@type": "xsd:string" 169 | }, 170 | "postalCode": { 171 | "@id": "clri:postalCode", 172 | "@type": "xsd:string" 173 | }, 174 | "publicKey": "sec:publicKey", 175 | "publisher": { 176 | "@id": "clri:publisher", 177 | "@type": "@id" 178 | }, 179 | "recipient": "obi:recipient", 180 | "requiredLevel": "clri:dtIRI", 181 | "requiredValue": { 182 | "@id": "clri:requiredValue", 183 | "@type": "xsd:string" 184 | }, 185 | "requirement": "obi:criteria", 186 | "resultDescription": "clri:dtIRI", 187 | "resultDescriptions": { 188 | "@id": "clri:dtResultDescription", 189 | "@container": "@set" 190 | }, 191 | "resultType": "clri:dtExtensibleResultType", 192 | "results": { 193 | "@id": "clri:dtResult", 194 | "@container": "@set" 195 | }, 196 | "role": { 197 | "@id": "clri:role", 198 | "@type": "xsd:string" 199 | }, 200 | "rubricCriterionLevels": { 201 | "@id": "clri:dtRubricCriterionLevel", 202 | "@container": "@set" 203 | }, 204 | "scopesOffered": { 205 | "@id": "clri:scopesOffered", 206 | "@type": "xsd:anyURI", 207 | "@container": "@set" 208 | }, 209 | "signedAssertions": { 210 | "@id": "clri:dtCompactJws", 211 | "@container": "@set" 212 | }, 213 | "signedClr": "clri:dtCompactJws", 214 | "signedClrs": { 215 | "@id": "clri:dtCompactJws", 216 | "@container": "@set" 217 | }, 218 | "signedEndorsements": { 219 | "@id": "clri:dtCompactJws", 220 | "@container": "@set" 221 | }, 222 | "source": "clri:dtProfile", 223 | "sourcedId": { 224 | "@id": "clri:sourcedId", 225 | "@type": "xsd:string" 226 | }, 227 | "specialization": { 228 | "@id": "clri:specialization", 229 | "@type": "xsd:string" 230 | }, 231 | "status": "clri:ResultStatusTypeDType", 232 | "streetAddress": { 233 | "@id": "clri:streetAddress", 234 | "@type": "xsd:string" 235 | }, 236 | "studentId": { 237 | "@id": "clri:studentId", 238 | "@type": "xsd:string" 239 | }, 240 | "targetId": "clri:dtIRI", 241 | "targetType": "clri:dtExtensibleAlignmentTargetType", 242 | "term": { 243 | "@id": "clri:term", 244 | "@type": "xsd:string" 245 | }, 246 | "title": { 247 | "@id": "clri:title", 248 | "@type": "xsd:string" 249 | }, 250 | "url": "schema:url", 251 | "value": { 252 | "@id": "clri:value", 253 | "@type": "xsd:string" 254 | }, 255 | "valueMax": { 256 | "@id": "clri:valueMax", 257 | "@type": "xsd:string" 258 | }, 259 | "valueMin": { 260 | "@id": "clri:valueMin", 261 | "@type": "xsd:string" 262 | }, 263 | "verification": "obi:verify", 264 | "Achievement": "dtAchievement", 265 | "Address": "dtAddress", 266 | "Alignment": "dtAlignment", 267 | "Artifact": "dtArtifact", 268 | "Assertion": "dtAssertion", 269 | "Association": "dtAssociation", 270 | "Clr": "dtClr", 271 | "Criteria": "dtCriteria", 272 | "CryptographicKey": "dtCryptographicKey", 273 | "Endorsement": "dtEndorsement", 274 | "EndorsementClaim": "dtEndorsementClaim", 275 | "EndorsementProfile": "dtEndorsementProfile", 276 | "Evidence": "dtEvidence", 277 | "ExtensibleAchievementType": "dtExtensibleAchievementType", 278 | "ExtensibleAlignmentTargetType": "dtExtensibleAlignmentTargetType", 279 | "ExtensibleResultType": "dtExtensibleResultType", 280 | "ExtensibleSystemIdentifierType": "dtExtensibleSystemIdentifierType", 281 | "Identity": "dtIdentity", 282 | "Profile": "dtProfile", 283 | "Result": "dtResult", 284 | "ResultDescription": "dtResultDescription", 285 | "RevocationList": "dtRevocationList", 286 | "RubricCriterionLevel": "dtRubricCriterionLevel", 287 | "SystemIdentifier": "dtSystemIdentifier", 288 | "Verification": "obi:VerificationObject", 289 | "CompactJws": "dtCompactJws", 290 | "EnumExtString": "dtEnumExtString", 291 | "IRI": "dtIRI", 292 | "Markdown": "dtMarkdown", 293 | "UUID": "dtUUID", 294 | "cred": "https://w3id.org/credentials/", 295 | "dc": "http://purl.org/dc/terms/", 296 | "obi": "https://w3id.org/openbadges#", 297 | "schema": "http://schema.org/", 298 | "sec": "https://w3id.org/security#", 299 | "additionalName": "schema:additionalName", 300 | "alignments": "obi:alignment", 301 | "allowedOrigins": "obi:allowedOrigins", 302 | "audience": "obi:audience", 303 | "authorizationUrl": { 304 | "@id": "clri:authorizationUrl", 305 | "@type": "@id" 306 | }, 307 | "creator": "dc:creator", 308 | "description": "schema:description", 309 | "email": "schema:email", 310 | "endorsements": "cred:credential", 311 | "expires": { 312 | "@id": "sec:expiration", 313 | "@type": "xsd:dateTime" 314 | }, 315 | "evidence": "obi:evidence", 316 | "familyName": "schema:familyName", 317 | "genre": "schema:genre", 318 | "givenName": "schema:givenName", 319 | "hashed": "obi:hashed", 320 | "identity": "obi:identityHash", 321 | "issuedOn": "obi:issueDate", 322 | "name": "schema:name", 323 | "privacyPolicyUrl": { 324 | "@id": "clri:privacyPolicyUrl", 325 | "@type": "@id" 326 | }, 327 | "publicKeyPem": "sec:publicKeyPem", 328 | "registrationUrl": { 329 | "@id": "clri:registrationUrl", 330 | "@type": "@id" 331 | }, 332 | "revocationList": "obi:revocationList", 333 | "revocationReason": "obi:revocationReason", 334 | "revoked": "obi:revoked", 335 | "revokedAssertions": "obi:revokedAssertions", 336 | "salt": "obi:salt", 337 | "startsWith": "obi:startsWith", 338 | "tags": "schema:keywords", 339 | "targetCode": "obi:targetCode", 340 | "targetDescription": "schema:targetDescription", 341 | "targetFramework": "schema:educationalFramework", 342 | "targetName": "schema:targetName", 343 | "targetUrl": "schema:targetUrl", 344 | "telephone": "schema:telephone", 345 | "termsOfServiceUrl": { 346 | "@id": "clri:termsOfServiceUrl", 347 | "@type": "@id" 348 | }, 349 | "tokenUrl": { 350 | "@id": "clri:tokenUrl", 351 | "@type": "@id" 352 | }, 353 | "verificationProperty": "obi:verificationProperty", 354 | "Hosted": "obi:hosted", 355 | "Signed": "obi:signed" 356 | } 357 | } -------------------------------------------------------------------------------- /resources/org.imsglobal.spec.clr.vocab.edn: -------------------------------------------------------------------------------- 1 | {"https://purl.imsglobal.org/spec/clr/vocab#dtAssertion" 2 | {:type ["http://www.w3.org/1999/02/22-rdf-syntax-ns#Property"] 3 | :iri "https://purl.imsglobal.org/spec/clr/vocab#dtAssertion", 4 | :id "https://purl.imsglobal.org/spec/clr/vocab#dtAssertion" 5 | :rdfs/label {:en "Assertions"}, 6 | :rdfs/comment "The learner's asserted achievements.", 7 | :rdfs/range [{:id "https://purl.imsglobal.org/spec/clr/vocab#Assertion" 8 | :iri "https://purl.imsglobal.org/spec/clr/vocab#Assertion"}] 9 | :fluree/type :ref} 10 | 11 | "https://purl.imsglobal.org/spec/clr/vocab#Assertion" 12 | {:type ["http://www.w3.org/2000/01/rdf-schema#Class"] 13 | :iri "https://purl.imsglobal.org/spec/clr/vocab#Assertion", 14 | :id "https://purl.imsglobal.org/spec/clr/vocab#Assertion" 15 | :rdfs/label {:en "Assertion"}, 16 | :rdfs/comment "Assertions are representations of an Achievement awarded to a Learner. It is used to share information about the Achievement Assertion, such as a result and verification method. ", 17 | :class? true} 18 | 19 | "https://purl.imsglobal.org/spec/clr/vocab#dtResult" 20 | {:type ["http://www.w3.org/1999/02/22-rdf-syntax-ns#Property"] 21 | :iri "https://purl.imsglobal.org/spec/clr/vocab#dtResult", 22 | :id "https://purl.imsglobal.org/spec/clr/vocab#dtResult" 23 | :rdfs/label {:en "Results"}, 24 | :rdfs/comment "The set of results being asserted." 25 | :rdfs/range [{:id "https://purl.imsglobal.org/spec/clr/vocab#Result" 26 | :iri "https://purl.imsglobal.org/spec/clr/vocab#Result"}] 27 | :fluree/type :ref} 28 | 29 | "https://purl.imsglobal.org/spec/clr/vocab#Result" 30 | {:type ["http://www.w3.org/2000/01/rdf-schema#Class"] 31 | :iri "https://purl.imsglobal.org/spec/clr/vocab#Result", 32 | :id "https://purl.imsglobal.org/spec/clr/vocab#Result" 33 | :rdfs/label {:en "Result"}, 34 | :rdfs/comment "Describes a result of an achievement." 35 | :class? true} 36 | 37 | "https://purl.imsglobal.org/spec/clr/vocab#dtIRI" 38 | {:type ["http://www.w3.org/1999/02/22-rdf-syntax-ns#Property"] 39 | :iri "https://purl.imsglobal.org/spec/clr/vocab#dtIRI", 40 | :id "https://purl.imsglobal.org/spec/clr/vocab#dtIRI" 41 | :rdfs/label {:en "IRIs"}, 42 | :rdfs/comment "IRI string." 43 | :fluree/type :string} 44 | 45 | "https://purl.imsglobal.org/spec/clr/vocab#dtAchievement" 46 | {:type ["http://www.w3.org/1999/02/22-rdf-syntax-ns#Property"] 47 | :iri "https://purl.imsglobal.org/spec/clr/vocab#dtAchievement", 48 | :id "https://purl.imsglobal.org/spec/clr/vocab#dtAchievement" 49 | :rdfs/label {:en "Results"}, 50 | :rdfs/comment "The set of achievements." 51 | :rdfs/range [{:id "https://purl.imsglobal.org/spec/clr/vocab#Achievement" 52 | :iri "https://purl.imsglobal.org/spec/clr/vocab#Achievement"}] 53 | :fluree/type :ref} 54 | 55 | "https://purl.imsglobal.org/spec/clr/vocab#Achievement" 56 | {:type ["http://www.w3.org/2000/01/rdf-schema#Class"] 57 | :iri "https://purl.imsglobal.org/spec/clr/vocab#Achievement", 58 | :id "https://purl.imsglobal.org/spec/clr/vocab#Achievement" 59 | :rdfs/label {:en "Achievement"}, 60 | :rdfs/comment "An accomplishment such as completing a degree, mastering a competency, or course completion that may be asserted about one or more learners." 61 | :class? true} 62 | 63 | "https://purl.imsglobal.org/spec/clr/vocab#creditsAvailable" 64 | {:type ["http://www.w3.org/1999/02/22-rdf-syntax-ns#Property"] 65 | :iri "https://purl.imsglobal.org/spec/clr/vocab#creditsAvailable", 66 | :id "https://purl.imsglobal.org/spec/clr/vocab#creditsAvailable" 67 | :rdfs/label {:en "Credits Available"}, 68 | :rdfs/comment "Credit hours associated with this entity, or credit hours possible. For example '3.0'." 69 | :fluree/type :float} 70 | 71 | "https://purl.imsglobal.org/spec/clr/vocab#EnumExtString" 72 | {:type ["http://www.w3.org/2000/01/rdf-schema#Class"], 73 | :class? true 74 | :enum? true 75 | :iri "https://purl.imsglobal.org/spec/clr/vocab#EnumExtString", 76 | :id "https://purl.imsglobal.org/spec/clr/vocab#EnumExtString", 77 | :rdfs/label {:en "Enumerated Extendable String"}, 78 | :rdfs/comment "The data-type that enables an enumerated vocabulary to be extended."} 79 | 80 | "https://purl.imsglobal.org/spec/clr/vocab#AchievementType" 81 | {:type ["http://www.w3.org/2000/01/rdf-schema#Class"], 82 | :class? true 83 | :enum? true 84 | :iri "https://purl.imsglobal.org/spec/clr/vocab#AchievementType", 85 | :id "https://purl.imsglobal.org/spec/clr/vocab#AchievementType", 86 | :rdfs/label {:en "Achievement Type"}, 87 | :rdfs/comment "The type of Achievement, an enumerated class."} 88 | 89 | "https://purl.imsglobal.org/spec/clr/vocab#dtExtensibleAchievementType" 90 | {:type ["http://www.w3.org/1999/02/22-rdf-syntax-ns#Property"], 91 | :rdfs/label {:en "Achievement Types"}, 92 | :iri "https://purl.imsglobal.org/spec/clr/vocab#dtExtensibleAchievementType" 93 | :id "https://purl.imsglobal.org/spec/clr/vocab#dtExtensibleAchievementType" 94 | :rdfs/comment "List of achievement types." 95 | :enum? true 96 | :fluree/type :ref} 97 | 98 | "https://purl.imsglobal.org/spec/clr/vocab#ExtensibleAchievementType" 99 | {:type ["http://www.w3.org/2000/01/rdf-schema#Class"], 100 | :class? true 101 | :enum? true 102 | :rdfs/subClassOf [{:id "https://purl.imsglobal.org/spec/clr/vocab#AchievementType", 103 | :iri "https://purl.imsglobal.org/spec/clr/vocab#AchievementType"} 104 | {:id "https://purl.imsglobal.org/spec/clr/vocab#EnumExtString", 105 | :iri "https://purl.imsglobal.org/spec/clr/vocab#EnumExtString"}] 106 | :iri "https://purl.imsglobal.org/spec/clr/vocab#ExtensibleAchievementType", 107 | :id "https://purl.imsglobal.org/spec/clr/vocab#ExtensibleAchievementType", 108 | :rdfs/label {:en "Extensible Achievement Type"}, 109 | :rdfs/comment "The type of achievement. This is an extensible enumerated vocabulary. Extending the vocabulary makes use of a naming convention"} 110 | 111 | "https://purl.imsglobal.org/spec/clr/vocab#AchievementResult" 112 | {:type ["http://www.w3.org/2000/01/rdf-schema#Class"], 113 | :class? true 114 | :enum? true 115 | :rdfs/subClassOf [{:id "https://purl.imsglobal.org/spec/clr/vocab#ExtensibleAchievementType", 116 | :iri "https://purl.imsglobal.org/spec/clr/vocab#ExtensibleAchievementType"}] 117 | :iri "https://purl.imsglobal.org/spec/clr/vocab#AchievementResult", 118 | :id "https://purl.imsglobal.org/spec/clr/vocab#AchievementResult", 119 | :rdfs/label {:en "Achievement Result"}, 120 | :rdfs/comment "Represents a generic achievement result"} 121 | 122 | "https://purl.imsglobal.org/spec/clr/vocab#dtResultDescription" 123 | {:type ["http://www.w3.org/1999/02/22-rdf-syntax-ns#Property"], 124 | :rdfs/label {:en "Result Descriptions"}, 125 | :iri "https://purl.imsglobal.org/spec/clr/vocab#dtResultDescription" 126 | :id "https://purl.imsglobal.org/spec/clr/vocab#dtResultDescription" 127 | :rdfs/comment "The set of result descriptions that may be asserted as results with this achievement." 128 | :fluree/type :ref} 129 | 130 | "https://purl.imsglobal.org/spec/clr/vocab#allowedValues" 131 | {:type ["http://www.w3.org/1999/02/22-rdf-syntax-ns#Property"], 132 | :rdfs/label {:en "Allowed Values"}, 133 | :iri "https://purl.imsglobal.org/spec/clr/vocab#allowedValues" 134 | :id "https://purl.imsglobal.org/spec/clr/vocab#allowedValues" 135 | :rdfs/comment "The ordered from 'low' to 'high' set of allowed values." 136 | :fluree/type :string} 137 | 138 | "https://purl.imsglobal.org/spec/clr/vocab#dtExtensibleResultType" 139 | {:type ["http://www.w3.org/1999/02/22-rdf-syntax-ns#Property"], 140 | :rdfs/label {:en "Result Types"}, 141 | :iri "https://purl.imsglobal.org/spec/clr/vocab#dtExtensibleResultType" 142 | :id "https://purl.imsglobal.org/spec/clr/vocab#dtExtensibleResultType" 143 | :rdfs/comment "The type of result. This is an extensible enumerated vocabulary" 144 | :enum? true 145 | :fluree/type :ref} 146 | 147 | "https://purl.imsglobal.org/spec/clr/vocab#ResultType" 148 | {:type ["http://www.w3.org/2000/01/rdf-schema#Class"], 149 | :class? true 150 | :enum? true 151 | :iri "https://purl.imsglobal.org/spec/clr/vocab#ResultType", 152 | :id "https://purl.imsglobal.org/spec/clr/vocab#ResultType", 153 | :rdfs/label {:en "Result Type"}, 154 | :rdfs/comment "The type of result claimed in the Achievement. Enumerated class."} 155 | 156 | "https://purl.imsglobal.org/spec/clr/vocab#ExtensibleResultType" 157 | {:type ["http://www.w3.org/2000/01/rdf-schema#Class"], 158 | :class? true 159 | :enum? true 160 | :rdfs/subClassOf [{:id "https://purl.imsglobal.org/spec/clr/vocab#ResultType", 161 | :iri "https://purl.imsglobal.org/spec/clr/vocab#ResultType"} 162 | {:id "https://purl.imsglobal.org/spec/clr/vocab#EnumExtString", 163 | :iri "https://purl.imsglobal.org/spec/clr/vocab#EnumExtString"}] 164 | :iri "https://purl.imsglobal.org/spec/clr/vocab#ExtensibleResultType", 165 | :id "https://purl.imsglobal.org/spec/clr/vocab#ExtensibleResultType", 166 | :rdfs/label {:en "Extensible Result Type"}, 167 | :rdfs/comment "The type of result. This is an extensible enumerated vocabulary. Extending the vocabulary makes use of a naming convention"} 168 | 169 | "https://purl.imsglobal.org/spec/clr/vocab#dtRubricCriterionLevel" 170 | {:type ["http://www.w3.org/1999/02/22-rdf-syntax-ns#Property"], 171 | :rdfs/label {:en "Rubric Criterion Levels"}, 172 | :iri "https://purl.imsglobal.org/spec/clr/vocab#dtRubricCriterionLevel" 173 | :id "https://purl.imsglobal.org/spec/clr/vocab#dtRubricCriterionLevel" 174 | :rdfs/comment "The ordered from 'low' to 'high' set of rubric criterion levels that may be asserted." 175 | :fluree/type :ref} 176 | 177 | "https://purl.imsglobal.org/spec/clr/vocab#dtAssociation" 178 | {:type ["http://www.w3.org/1999/02/22-rdf-syntax-ns#Property"], 179 | :rdfs/label {:en "Associations"}, 180 | :iri "https://purl.imsglobal.org/spec/clr/vocab#dtAssociation" 181 | :id "https://purl.imsglobal.org/spec/clr/vocab#dtAssociation" 182 | :rdfs/comment "Associations between this achievement and other achievements." 183 | :fluree/type :ref} 184 | 185 | "https://purl.imsglobal.org/spec/clr/vocab#creditsEarned" 186 | {:type ["http://www.w3.org/1999/02/22-rdf-syntax-ns#Property"], 187 | :rdfs/label {:en "Credits Earned"}, 188 | :iri "https://purl.imsglobal.org/spec/clr/vocab#creditsEarned" 189 | :id "https://purl.imsglobal.org/spec/clr/vocab#creditsEarned" 190 | :rdfs/comment "The number of credits earned, generally in semester or quarter credit hours. This field correlates with the Achievement creditsAvailable field." 191 | :fluree/type :float} 192 | 193 | "https://purl.imsglobal.org/spec/clr/vocab#activityStartDate" 194 | {:type ["http://www.w3.org/1999/02/22-rdf-syntax-ns#Property"] 195 | :iri "https://purl.imsglobal.org/spec/clr/vocab#activityStartDate", 196 | :id "https://purl.imsglobal.org/spec/clr/vocab#activityStartDate" 197 | :rdfs/label {:en "Activity Start Date"}, 198 | :rdfs/comment "If present, start date for the activity.", 199 | :fluree/type :dateTime} 200 | 201 | "https://purl.imsglobal.org/spec/clr/vocab#activityEndDate" 202 | {:type ["http://www.w3.org/1999/02/22-rdf-syntax-ns#Property"] 203 | :iri "https://purl.imsglobal.org/spec/clr/vocab#activityEndDate", 204 | :id "https://purl.imsglobal.org/spec/clr/vocab#activityEndDate" 205 | :rdfs/label {:en "Activity End Date"}, 206 | :rdfs/comment "If present, end date for the activity.", 207 | :fluree/type :dateTime} 208 | 209 | 210 | #_{:rdfs/subClassOf 211 | [{:id "https://schema.org/CreativeWork", 212 | :iri "https://schema.org/CreativeWork"}], 213 | :extra 214 | {"https://schema.org/isPartOf" "https://pending.schema.org", 215 | "https://schema.org/source" 216 | ["https://github.com/schemaorg/schemaorg/issues/2358"]}, 217 | :class? true, 218 | :type ["http://www.w3.org/2000/01/rdf-schema#Class"], 219 | :rdfs/label {:en "WebContent"}, 220 | :id "https://schema.org/WebContent", 221 | :rdfs/comment 222 | "WebContent is a type representing all [[WebPage]], [[WebSite]] and [[WebPageElement]] content. It is sometimes the case that detailed distinctions between Web pages, sites and their parts is not always important or obvious. The [[WebContent]] type makes it easier to describe Web-addressable content without requiring such distinctions to always be stated. (The intent is that the existing types [[WebPage]], [[WebSite]] and [[WebPageElement]] will eventually be declared as subtypes of [[WebContent]]).", 223 | :iri "https://schema.org/WebContent"} 224 | 225 | } -------------------------------------------------------------------------------- /resources/org.w3id.openbadges.edn: -------------------------------------------------------------------------------- 1 | {"https://w3id.org/openbadges#issueDate" 2 | {:type ["http://www.w3.org/1999/02/22-rdf-syntax-ns#Property"] 3 | :iri "https://w3id.org/openbadges#issueDate", 4 | :id "https://w3id.org/openbadges#issueDate" 5 | :rdfs/label {:en "Issued On"}, 6 | :rdfs/comment "Timestamp of when awarded", 7 | :fluree/type :dateTime} 8 | 9 | "https://w3id.org/openbadges#verify" 10 | {:type ["http://www.w3.org/1999/02/22-rdf-syntax-ns#Property"] 11 | :iri "https://w3id.org/openbadges#verify", 12 | :id "https://w3id.org/openbadges#verify" 13 | :rdfs/label {:en "Verification"}, 14 | :rdfs/comment "Instructions for third parties to verify this assertion.", 15 | :fluree/type :ref} 16 | 17 | "https://w3id.org/openbadges#verificationProperty" 18 | {:type ["http://www.w3.org/1999/02/22-rdf-syntax-ns#Property"] 19 | :iri "https://w3id.org/openbadges#verificationProperty", 20 | :id "https://w3id.org/openbadges#verificationProperty" 21 | :rdfs/label {:en "Verification Property"}, 22 | :rdfs/comment "The @id of the property to be used for verification that an Assertion is within the allowed scope. Only id is supported. Verifiers will consider id the default value if verificationProperty is omitted or if an issuer Profile has no explicit verification instructions, so it may be safely omitted.", 23 | :fluree/type :string} 24 | 25 | "https://w3id.org/openbadges#recipient" 26 | {:type ["http://www.w3.org/1999/02/22-rdf-syntax-ns#Property"] 27 | :iri "https://w3id.org/openbadges#recipient", 28 | :id "https://w3id.org/openbadges#recipient" 29 | :rdfs/label {:en "recipient"}, 30 | :rdfs/comment "The recipient of the achievement." 31 | :fluree/type :ref} 32 | 33 | "https://w3id.org/openbadges#identityHash" 34 | {:type ["http://www.w3.org/1999/02/22-rdf-syntax-ns#Property"] 35 | :iri "https://w3id.org/openbadges#identityHash", 36 | :id "https://w3id.org/openbadges#identityHash" 37 | :rdfs/label {:en "Identity Hash"}, 38 | :rdfs/comment "Either the hash of the identity or the plaintext value. If it's possible that the plaintext transmission and storage of the identity value would leak personally identifiable information where there is an expectation of privacy, it is strongly recommended that an IdentityHash be used." 39 | :fluree/type :string} 40 | 41 | "https://w3id.org/openbadges#hashed" 42 | {:type ["http://www.w3.org/1999/02/22-rdf-syntax-ns#Property"] 43 | :iri "https://w3id.org/openbadges#hashed", 44 | :id "https://w3id.org/openbadges#hashed" 45 | :rdfs/label {:en "Hashed?"}, 46 | :rdfs/comment "Whether or not the identity value is hashed." 47 | :fluree/type :boolean} 48 | 49 | "https://w3id.org/openbadges#alignment" 50 | {:type ["http://www.w3.org/1999/02/22-rdf-syntax-ns#Property"] 51 | :iri "https://w3id.org/openbadges#alignment", 52 | :id "https://w3id.org/openbadges#alignment" 53 | :rdfs/label {:en "Alignment"}, 54 | :rdfs/comment "An object describing which objectives or educational standards this badge aligns to, if any." 55 | :fluree/type :ref 56 | :rdfs/range [{:id "https://schema.org/AlignmentObject" 57 | :iri "https://schema.org/AlignmentObject"}]} 58 | 59 | "https://w3id.org/openbadges#issuer" 60 | {:type ["http://www.w3.org/1999/02/22-rdf-syntax-ns#Property"] 61 | :iri "https://w3id.org/openbadges#issuer", 62 | :id "https://w3id.org/openbadges#issuer" 63 | :rdfs/label {:en "Issuer"}, 64 | :rdfs/comment "IRI or document describing the individual, entity, or organization that issued the badge" 65 | :fluree/type :ref 66 | :rdfs/range [{:id "https://schema.org/AlignmentObject" 67 | :iri "https://schema.org/AlignmentObject"}]} 68 | 69 | "https://w3id.org/openbadges#evidence" 70 | {:type ["http://www.w3.org/1999/02/22-rdf-syntax-ns#Property"] 71 | :iri "https://w3id.org/openbadges#evidence", 72 | :id "https://w3id.org/openbadges#evidence" 73 | :rdfs/label {:en "Evidence"}, 74 | :rdfs/comment "IRI or document describing the work that the recipient did to earn the achievement. This can be a page that links out to other pages if linking directly to the work is infeasible." 75 | :fluree/type :ref} 76 | 77 | "https://w3id.org/openbadges#criteria" 78 | {:type ["http://www.w3.org/1999/02/22-rdf-syntax-ns#Property"] 79 | :iri "https://w3id.org/openbadges#criteria", 80 | :id "https://w3id.org/openbadges#criteria" 81 | :rdfs/label {:en "criteria"}, 82 | :rdfs/comment "URI or embedded criteria document describing how to earn the achievement." 83 | :fluree/type :ref} 84 | 85 | 86 | } 87 | 88 | 89 | 90 | ;; :type ["http://www.w3.org/2000/01/rdf-schema#Class"], -------------------------------------------------------------------------------- /resources/owl.edn.bak: -------------------------------------------------------------------------------- 1 | {"http://www.w3.org/2002/07/owl#Class" 2 | {:id "http://www.w3.org/2002/07/owl#Class", 3 | :iri "http://www.w3.org/2002/07/owl#Class", 4 | :type ["http://www.w3.org/2000/01/rdf-schema#Class"], 5 | :class? true, 6 | :rdfs/subClassOf 7 | [{:id "http://www.w3.org/2000/01/rdf-schema#Class", 8 | :iri "http://www.w3.org/2000/01/rdf-schema#Class"}] 9 | :rdfs/comment 10 | "OWL Class Definition.", 11 | :rdfs/label {:en "OWL Class Definition"}}, 12 | "http://www.w3.org/2002/07/owl#ObjectProperty" 13 | {:id "http://www.w3.org/2002/07/owl#ObjectProperty", 14 | :iri "http://www.w3.org/2002/07/owl#ObjectProperty", 15 | :type ["http://www.w3.org/1999/02/22-rdf-syntax-ns#Property"], 16 | :class? true, 17 | :rdfs/subClassOf 18 | [{:id "http://www.w3.org/1999/02/22-rdf-syntax-ns#Property", 19 | :iri "http://www.w3.org/1999/02/22-rdf-syntax-ns#Property"}] 20 | :rdfs/comment 21 | "OWL Object properties link individuals to individuals.", 22 | :rdfs/label {:en "OWL Object properties link individuals to individuals."}} 23 | "http://www.w3.org/2002/07/owl#DatatypeProperty" 24 | {:id "http://www.w3.org/2002/07/owl#DatatypeProperty", 25 | :iri "http://www.w3.org/2002/07/owl#DatatypeProperty", 26 | :type ["http://www.w3.org/1999/02/22-rdf-syntax-ns#Property"], 27 | :class? true, 28 | :rdfs/subClassOf 29 | [{:id "http://www.w3.org/1999/02/22-rdf-syntax-ns#Property", 30 | :iri "http://www.w3.org/1999/02/22-rdf-syntax-ns#Property"}] 31 | :rdfs/comment 32 | "OWL Datatype properties link individuals to data values.", 33 | :rdfs/label {:en "OWL Datatype properties link individuals to data values."}}} -------------------------------------------------------------------------------- /resources/rdfs.edn: -------------------------------------------------------------------------------- 1 | {"http://www.w3.org/2000/01/rdf-schema#seeAlso" 2 | {:rdfs/domain 3 | [{:id "http://www.w3.org/2000/01/rdf-schema#Resource", 4 | :iri "http://www.w3.org/2000/01/rdf-schema#Resource"}], 5 | :type ["http://www.w3.org/1999/02/22-rdf-syntax-ns#Property"], 6 | :rdfs/isDefinedBy 7 | [{:id "http://www.w3.org/2000/01/rdf-schema#", 8 | :iri "http://www.w3.org/2000/01/rdf-schema#"}], 9 | :fluree/type :ref, 10 | :rdfs/label {:en "seeAlso"}, 11 | :id "http://www.w3.org/2000/01/rdf-schema#seeAlso", 12 | :rdfs/comment "Further information about the subject resource.", 13 | :iri "http://www.w3.org/2000/01/rdf-schema#seeAlso", 14 | :rdfs/range 15 | [{:id "http://www.w3.org/2000/01/rdf-schema#Resource", 16 | :iri "http://www.w3.org/2000/01/rdf-schema#Resource"}]}, 17 | "http://www.w3.org/2000/01/rdf-schema#member" 18 | {:rdfs/domain 19 | [{:id "http://www.w3.org/2000/01/rdf-schema#Resource", 20 | :iri "http://www.w3.org/2000/01/rdf-schema#Resource"}], 21 | :type ["http://www.w3.org/1999/02/22-rdf-syntax-ns#Property"], 22 | :rdfs/isDefinedBy 23 | [{:id "http://www.w3.org/2000/01/rdf-schema#", 24 | :iri "http://www.w3.org/2000/01/rdf-schema#"}], 25 | :fluree/type :ref, 26 | :rdfs/label {:en "member"}, 27 | :id "http://www.w3.org/2000/01/rdf-schema#member", 28 | :rdfs/comment "A member of the subject resource.", 29 | :iri "http://www.w3.org/2000/01/rdf-schema#member", 30 | :rdfs/range 31 | [{:id "http://www.w3.org/2000/01/rdf-schema#Resource", 32 | :iri "http://www.w3.org/2000/01/rdf-schema#Resource"}]}, 33 | "http://www.w3.org/2000/01/rdf-schema#Literal" 34 | {:id "http://www.w3.org/2000/01/rdf-schema#Literal", 35 | :iri "http://www.w3.org/2000/01/rdf-schema#Literal", 36 | :type ["http://www.w3.org/2000/01/rdf-schema#Class"], 37 | :rdfs/isDefinedBy 38 | [{:id "http://www.w3.org/2000/01/rdf-schema#", 39 | :iri "http://www.w3.org/2000/01/rdf-schema#"}], 40 | :rdfs/label {:en "Literal"}, 41 | :rdfs/comment 42 | "The class of literal values, eg. textual strings and integers.", 43 | :rdfs/subClassOf 44 | [{:id "http://www.w3.org/2000/01/rdf-schema#Resource", 45 | :iri "http://www.w3.org/2000/01/rdf-schema#Resource"}], 46 | :class? true}, 47 | "http://www.w3.org/2000/01/rdf-schema#Resource" 48 | {:id "http://www.w3.org/2000/01/rdf-schema#Resource", 49 | :iri "http://www.w3.org/2000/01/rdf-schema#Resource", 50 | :type ["http://www.w3.org/2000/01/rdf-schema#Class"], 51 | :rdfs/isDefinedBy 52 | [{:id "http://www.w3.org/2000/01/rdf-schema#", 53 | :iri "http://www.w3.org/2000/01/rdf-schema#"}], 54 | :rdfs/label {:en "Resource"}, 55 | :rdfs/comment "The class resource, everything.", 56 | :class? true}, 57 | "http://www.w3.org/2000/01/rdf-schema#Container" 58 | {:id "http://www.w3.org/2000/01/rdf-schema#Container", 59 | :iri "http://www.w3.org/2000/01/rdf-schema#Container", 60 | :type ["http://www.w3.org/2000/01/rdf-schema#Class"], 61 | :rdfs/isDefinedBy 62 | [{:id "http://www.w3.org/2000/01/rdf-schema#", 63 | :iri "http://www.w3.org/2000/01/rdf-schema#"}], 64 | :rdfs/label {:en "Container"}, 65 | :rdfs/subClassOf 66 | [{:id "http://www.w3.org/2000/01/rdf-schema#Resource", 67 | :iri "http://www.w3.org/2000/01/rdf-schema#Resource"}], 68 | :rdfs/comment "The class of RDF containers.", 69 | :class? true}, 70 | "http://www.w3.org/2000/01/rdf-schema#domain" 71 | {:rdfs/domain 72 | [{:id "http://www.w3.org/1999/02/22-rdf-syntax-ns#Property", 73 | :iri "http://www.w3.org/1999/02/22-rdf-syntax-ns#Property"}], 74 | :type ["http://www.w3.org/1999/02/22-rdf-syntax-ns#Property"], 75 | :rdfs/isDefinedBy 76 | [{:id "http://www.w3.org/2000/01/rdf-schema#", 77 | :iri "http://www.w3.org/2000/01/rdf-schema#"}], 78 | :fluree/type :ref, 79 | :rdfs/label {:en "domain"}, 80 | :id "http://www.w3.org/2000/01/rdf-schema#domain", 81 | :rdfs/comment "A domain of the subject property.", 82 | :iri "http://www.w3.org/2000/01/rdf-schema#domain", 83 | :fluree/restrictCollection 84 | [{:id "http://www.w3.org/2000/01/rdf-schema#Class", 85 | :iri "http://www.w3.org/2000/01/rdf-schema#Class"}], 86 | :rdfs/range 87 | [{:id "http://www.w3.org/2000/01/rdf-schema#Class", 88 | :iri "http://www.w3.org/2000/01/rdf-schema#Class"}]}, 89 | "http://www.w3.org/2000/01/rdf-schema#subClassOf" 90 | {:rdfs/domain 91 | [{:id "http://www.w3.org/2000/01/rdf-schema#Class", 92 | :iri "http://www.w3.org/2000/01/rdf-schema#Class"}], 93 | :type ["http://www.w3.org/1999/02/22-rdf-syntax-ns#Property"], 94 | :rdfs/isDefinedBy 95 | [{:id "http://www.w3.org/2000/01/rdf-schema#", 96 | :iri "http://www.w3.org/2000/01/rdf-schema#"}], 97 | :fluree/type :ref, 98 | :rdfs/label {:en "subClassOf"}, 99 | :id "http://www.w3.org/2000/01/rdf-schema#subClassOf", 100 | :rdfs/comment "The subject is a subclass of a class.", 101 | :iri "http://www.w3.org/2000/01/rdf-schema#subClassOf", 102 | :fluree/restrictCollection 103 | [{:id "http://www.w3.org/2000/01/rdf-schema#Class", 104 | :iri "http://www.w3.org/2000/01/rdf-schema#Class"}], 105 | :rdfs/range 106 | [{:id "http://www.w3.org/2000/01/rdf-schema#Class", 107 | :iri "http://www.w3.org/2000/01/rdf-schema#Class"}]}, 108 | "http://www.w3.org/2000/01/rdf-schema#isDefinedBy" 109 | {:rdfs/domain 110 | [{:id "http://www.w3.org/2000/01/rdf-schema#Resource", 111 | :iri "http://www.w3.org/2000/01/rdf-schema#Resource"}], 112 | :rdfs/subPropertyOf 113 | [{:id "http://www.w3.org/2000/01/rdf-schema#seeAlso", 114 | :iri "http://www.w3.org/2000/01/rdf-schema#seeAlso"}], 115 | :type ["http://www.w3.org/1999/02/22-rdf-syntax-ns#Property"], 116 | :rdfs/isDefinedBy 117 | [{:id "http://www.w3.org/2000/01/rdf-schema#", 118 | :iri "http://www.w3.org/2000/01/rdf-schema#"}], 119 | :fluree/type :ref, 120 | :rdfs/label {:en "isDefinedBy"}, 121 | :id "http://www.w3.org/2000/01/rdf-schema#isDefinedBy", 122 | :rdfs/comment "The defininition of the subject resource.", 123 | :iri "http://www.w3.org/2000/01/rdf-schema#isDefinedBy", 124 | :rdfs/range 125 | [{:id "http://www.w3.org/2000/01/rdf-schema#Resource", 126 | :iri "http://www.w3.org/2000/01/rdf-schema#Resource"}]}, 127 | "http://www.w3.org/2000/01/rdf-schema#Datatype" 128 | {:id "http://www.w3.org/2000/01/rdf-schema#Datatype", 129 | :iri "http://www.w3.org/2000/01/rdf-schema#Datatype", 130 | :type ["http://www.w3.org/2000/01/rdf-schema#Class"], 131 | :rdfs/isDefinedBy 132 | [{:id "http://www.w3.org/2000/01/rdf-schema#", 133 | :iri "http://www.w3.org/2000/01/rdf-schema#"}], 134 | :rdfs/label {:en "Datatype"}, 135 | :rdfs/comment "The class of RDF datatypes.", 136 | :rdfs/subClassOf 137 | [{:id "http://www.w3.org/2000/01/rdf-schema#Class", 138 | :iri "http://www.w3.org/2000/01/rdf-schema#Class"}], 139 | :class? true}, 140 | "http://www.w3.org/2000/01/rdf-schema#comment" 141 | {:rdfs/domain 142 | [{:id "http://www.w3.org/2000/01/rdf-schema#Resource", 143 | :iri "http://www.w3.org/2000/01/rdf-schema#Resource"}], 144 | :type ["http://www.w3.org/1999/02/22-rdf-syntax-ns#Property"], 145 | :rdfs/isDefinedBy 146 | [{:id "http://www.w3.org/2000/01/rdf-schema#", 147 | :iri "http://www.w3.org/2000/01/rdf-schema#"}], 148 | :fluree/type :string, 149 | :rdfs/label {:en "comment"}, 150 | :id "http://www.w3.org/2000/01/rdf-schema#comment", 151 | :rdfs/comment "A description of the subject resource.", 152 | :iri "http://www.w3.org/2000/01/rdf-schema#comment", 153 | :rdfs/range 154 | [{:id "http://www.w3.org/2000/01/rdf-schema#Literal", 155 | :iri "http://www.w3.org/2000/01/rdf-schema#Literal"}]}, 156 | "http://www.w3.org/2000/01/rdf-schema#Class" 157 | {:id "http://www.w3.org/2000/01/rdf-schema#Class", 158 | :iri "http://www.w3.org/2000/01/rdf-schema#Class", 159 | :type ["http://www.w3.org/2000/01/rdf-schema#Class"], 160 | :rdfs/isDefinedBy 161 | [{:id "http://www.w3.org/2000/01/rdf-schema#", 162 | :iri "http://www.w3.org/2000/01/rdf-schema#"}], 163 | :rdfs/label {:en "Class"}, 164 | :rdfs/comment "The class of classes.", 165 | :rdfs/subClassOf 166 | [{:id "http://www.w3.org/2000/01/rdf-schema#Resource", 167 | :iri "http://www.w3.org/2000/01/rdf-schema#Resource"}], 168 | :class? true}, 169 | "http://www.w3.org/2000/01/rdf-schema#ContainerMembershipProperty" 170 | {:id 171 | "http://www.w3.org/2000/01/rdf-schema#ContainerMembershipProperty", 172 | :iri 173 | "http://www.w3.org/2000/01/rdf-schema#ContainerMembershipProperty", 174 | :type ["http://www.w3.org/2000/01/rdf-schema#Class"], 175 | :rdfs/isDefinedBy 176 | [{:id "http://www.w3.org/2000/01/rdf-schema#", 177 | :iri "http://www.w3.org/2000/01/rdf-schema#"}], 178 | :rdfs/label {:en "ContainerMembershipProperty"}, 179 | :rdfs/comment 180 | "The class of container membership properties, rdf:_1, rdf:_2, ...,\r\n all of which are sub-properties of 'member'.", 181 | :rdfs/subClassOf 182 | [{:id "http://www.w3.org/1999/02/22-rdf-syntax-ns#Property", 183 | :iri "http://www.w3.org/1999/02/22-rdf-syntax-ns#Property"}], 184 | :class? true}, 185 | "http://www.w3.org/2000/01/rdf-schema#range" 186 | {:rdfs/domain 187 | [{:id "http://www.w3.org/1999/02/22-rdf-syntax-ns#Property", 188 | :iri "http://www.w3.org/1999/02/22-rdf-syntax-ns#Property"}], 189 | :type ["http://www.w3.org/1999/02/22-rdf-syntax-ns#Property"], 190 | :rdfs/isDefinedBy 191 | [{:id "http://www.w3.org/2000/01/rdf-schema#", 192 | :iri "http://www.w3.org/2000/01/rdf-schema#"}], 193 | :fluree/type :ref, 194 | :rdfs/label {:en "range"}, 195 | :id "http://www.w3.org/2000/01/rdf-schema#range", 196 | :rdfs/comment "A range of the subject property.", 197 | :iri "http://www.w3.org/2000/01/rdf-schema#range", 198 | :fluree/restrictCollection 199 | [{:id "http://www.w3.org/2000/01/rdf-schema#Class", 200 | :iri "http://www.w3.org/2000/01/rdf-schema#Class"}], 201 | :rdfs/range 202 | [{:id "http://www.w3.org/2000/01/rdf-schema#Class", 203 | :iri "http://www.w3.org/2000/01/rdf-schema#Class"}]}, 204 | "http://www.w3.org/2000/01/rdf-schema#subPropertyOf" 205 | {:rdfs/domain 206 | [{:id "http://www.w3.org/1999/02/22-rdf-syntax-ns#Property", 207 | :iri "http://www.w3.org/1999/02/22-rdf-syntax-ns#Property"}], 208 | :type ["http://www.w3.org/1999/02/22-rdf-syntax-ns#Property"], 209 | :rdfs/isDefinedBy 210 | [{:id "http://www.w3.org/2000/01/rdf-schema#", 211 | :iri "http://www.w3.org/2000/01/rdf-schema#"}], 212 | :fluree/type :ref, 213 | :rdfs/label {:en "subPropertyOf"}, 214 | :id "http://www.w3.org/2000/01/rdf-schema#subPropertyOf", 215 | :rdfs/comment "The subject is a subproperty of a property.", 216 | :iri "http://www.w3.org/2000/01/rdf-schema#subPropertyOf", 217 | :fluree/restrictCollection 218 | [{:id "http://www.w3.org/1999/02/22-rdf-syntax-ns#Property", 219 | :iri "http://www.w3.org/1999/02/22-rdf-syntax-ns#Property"}], 220 | :rdfs/range 221 | [{:id "http://www.w3.org/1999/02/22-rdf-syntax-ns#Property", 222 | :iri "http://www.w3.org/1999/02/22-rdf-syntax-ns#Property"}]}, 223 | "http://www.w3.org/2000/01/rdf-schema#label" 224 | {:rdfs/domain 225 | [{:id "http://www.w3.org/2000/01/rdf-schema#Resource", 226 | :iri "http://www.w3.org/2000/01/rdf-schema#Resource"}], 227 | :type ["http://www.w3.org/1999/02/22-rdf-syntax-ns#Property"], 228 | :rdfs/isDefinedBy 229 | [{:id "http://www.w3.org/2000/01/rdf-schema#", 230 | :iri "http://www.w3.org/2000/01/rdf-schema#"}], 231 | :fluree/type :string, 232 | :rdfs/label {:en "label"}, 233 | :id "http://www.w3.org/2000/01/rdf-schema#label", 234 | :rdfs/comment "A human-readable name for the subject.", 235 | :iri "http://www.w3.org/2000/01/rdf-schema#label", 236 | :rdfs/range 237 | [{:id "http://www.w3.org/2000/01/rdf-schema#Literal", 238 | :iri "http://www.w3.org/2000/01/rdf-schema#Literal"}]}, 239 | "http://www.w3.org/2000/01/rdf-schema#" 240 | {:id "http://www.w3.org/2000/01/rdf-schema#", 241 | :iri "http://www.w3.org/2000/01/rdf-schema#", 242 | :type ["http://www.w3.org/2002/07/owl#Ontology"], 243 | "http://purl.org/dc/elements/1.1/title" 244 | [{"@value" "The RDF Schema vocabulary (RDFS)"}], 245 | :rdfs/seeAlso 246 | [{:id "http://www.w3.org/2000/01/rdf-schema-more", 247 | :iri "http://www.w3.org/2000/01/rdf-schema-more"}]}} -------------------------------------------------------------------------------- /shadow-cljs.edn: -------------------------------------------------------------------------------- 1 | 2 | {:deps {:aliases [:dev]} 3 | 4 | :builds 5 | {:nodejs-test ; runs the cljs tests on node 6 | {:target :node-test 7 | :output-to "test/nodejs/node-tests.js" 8 | :autorun true 9 | :compiler-options {:optimizations :simple}} 10 | 11 | :browser-test ; runs the cljs tests in the browser via karma 12 | {:target :karma 13 | :output-to "test/browser/browser-tests.js"}}} 14 | -------------------------------------------------------------------------------- /src/fluree/json_ld.cljc: -------------------------------------------------------------------------------- 1 | (ns fluree.json-ld 2 | (:require [fluree.json-ld.impl.context :as context] 3 | [fluree.json-ld.impl.compact :as compact] 4 | [fluree.json-ld.impl.expand :as expand] 5 | [fluree.json-ld.impl.normalize :as normalize] 6 | [fluree.json-ld.impl.external :as external])) 7 | 8 | #?(:clj (set! *warn-on-reflection* true)) 9 | 10 | (defn parse-context 11 | "Parses a JSON-LD context and returns a Clojure map (or error if context invalid). 12 | 13 | If a base-context is provided, merges new context into base context. base-context 14 | must already be a parsed context. 15 | 16 | externals, if provided, is a set of external context URLs that are safe to load. Currently 17 | will only load external contexts that are pre-parsed and saved locally with this library, 18 | the default list of which is at fluree.json-ld.impl.external/external-contexts" 19 | ([context] (context/parse {} external/external-contexts context)) 20 | ([base-context context] 21 | (context/parse base-context external/external-contexts context)) 22 | ([base-context externals context] 23 | (context/parse base-context externals context))) 24 | 25 | 26 | (defn external-vocab 27 | "Loads a supported external vocabulary for a specific iri, which should be 28 | a class or predicate. 29 | 30 | The vocab will include information beyond a context mapping, i.e. rdfs:subClassOf." 31 | [iri] 32 | (external/vocab iri)) 33 | 34 | (defn external-iri 35 | "Loads a supported external vocabulary for a specific iri, which should be 36 | a class or predicate. 37 | 38 | The vocab will include information beyond a context mapping, i.e. rdfs:subClassOf." 39 | [iri] 40 | (external/iri iri)) 41 | 42 | 43 | (defn external-context 44 | "Loads a pre-fetched, parsed context based on URL that may be used as a @context value. 45 | Note this is not a vocabulary, but just a context mapping. It may end up using many different 46 | vocabularies as part of its mapping.. 47 | 48 | Returns nil if context not pre-fetched." 49 | [url] 50 | (external/context url)) 51 | 52 | 53 | (defn compact 54 | "Returns compacted iri when provided parsed context." 55 | [iri parsed-context-or-fn] 56 | (compact/compact iri parsed-context-or-fn)) 57 | 58 | 59 | (defn compact-fn 60 | "Returns compacting fn based on the provided parsed context 61 | that takes a single argument string IRI and returns compacted IRI. 62 | 63 | If IRI cannot be compacted, returns original IRI. 64 | 65 | Optionally, a second param, used-atom (a Clojure atom), can be supplied which captures all 66 | context items that were used. This is useful when a large context is present which only a 67 | small subset will be used, and you want to know which subset were used." 68 | ([parsed-context] 69 | (compact/compact-fn parsed-context nil)) 70 | ([parsed-context used-atom] 71 | (compact/compact-fn parsed-context used-atom))) 72 | 73 | 74 | (defn expand-iri 75 | "Expands a compacted iri string to full iri. 76 | 77 | If vocab? is true, it will expand based on the value being a property/class (@type) 78 | and utilize the context's :vocab value, if defined. If vocab? is falsey, will 79 | treat compact-iri as an @id, and will utilize the context's :base value, if defined. 80 | 81 | If the iri is not compacted, returns original iri string." 82 | ([compact-iri parsed-context] 83 | (expand/iri compact-iri parsed-context true)) 84 | ([compact-iri parsed-context vocab?] 85 | (expand/iri compact-iri parsed-context vocab?))) 86 | 87 | 88 | (defn expand 89 | "Expands an entire JSON-LD node (JSON object), with optional parsed context 90 | provided. If node has a local context, will merge with provided parse-context. 91 | 92 | Expands into child nodes." 93 | ([node-map] 94 | (expand/node node-map {})) 95 | ([node-map parsed-context] 96 | (expand/node node-map parsed-context))) 97 | 98 | 99 | (defn details 100 | "Like expand, but returns two-tuple of expanded iri followed by 101 | a map of any context settings for that iri. 102 | 103 | If vocab? is true, it will expand based on the value being a property/class (@type) 104 | and utilize the context's :vocab value, if defined. If vocab? is falsey, will 105 | treat compact-iri as an @id, and will utilize the context's :base value, if defined. 106 | 107 | If no match exists, returns original compact-iri as first element 108 | and nil for second." 109 | ([compact-iri parsed-context] 110 | (expand/details compact-iri parsed-context true)) 111 | ([compact-iri parsed-context vocab?] 112 | (expand/details compact-iri parsed-context vocab?))) 113 | 114 | 115 | (defn json-ld? 116 | "Returns true if the provided document looks like json-ld." 117 | [x] 118 | (boolean 119 | (or 120 | (get x "@graph") 121 | (get-in x [0 "@context"]) 122 | (get-in x [0 "@id"])))) 123 | 124 | 125 | (defn normalize-data 126 | "Normalizes a Clojure data structure into a string based on provided options which 127 | include 128 | :algorithm - :basic or :URDNA2015 (not yet supported) 129 | :format - what format to put data into :application/json (default) :application/n-quads (not yet supported) 130 | 131 | Used to get a consistent format/hash for data regardless of input." 132 | ([data] (normalize/normalize data)) 133 | ([data opts] 134 | (normalize/normalize data opts))) 135 | -------------------------------------------------------------------------------- /src/fluree/json_ld/impl/compact.cljc: -------------------------------------------------------------------------------- 1 | (ns fluree.json-ld.impl.compact 2 | (:require [clojure.string :as str])) 3 | 4 | #?(:clj (set! *warn-on-reflection* true)) 5 | 6 | (defn- reverse-context 7 | "Flips context map from prefix -> prefix-map, to iri -> prefix-map. 8 | 9 | Only includes context items that have an :id; i.e., @id. 10 | Excludes non-id context statements (e.g., @reverse)." 11 | [context] 12 | (loop [[[prefix v] & r] context 13 | acc {}] 14 | (if prefix 15 | (let [iri-fragment (:id v) 16 | acc* (cond 17 | iri-fragment (assoc acc iri-fragment prefix) 18 | (= :vocab prefix) (assoc acc v :vocab) 19 | (= :base prefix) (assoc acc v :base) 20 | :else acc)] 21 | (recur r acc*)) 22 | acc))) 23 | 24 | 25 | (defn- add-match-to-used-atom 26 | "If 'used' atom is provided to record all used context values, this 27 | adds any matches to used atom. 28 | 29 | 'used' atom is to return a small context if desired of only matching values, 30 | as opposed to, e.g. the entire schema.org context containing thousands of items 31 | when only one might have been actually used." 32 | [prefix-matched iri used-atom] 33 | (let [key (if (keyword? prefix-matched) 34 | (case prefix-matched 35 | :vocab "@vocab" 36 | :base "@base" 37 | ;;else 38 | (name prefix-matched)) 39 | prefix-matched)] 40 | (swap! used-atom assoc key iri))) 41 | 42 | 43 | (defn- partial-iri-match 44 | "If the input iri is a match to a prefix value, 45 | e.g. the input iri is http://example.com/ns#t 46 | with a context of: {'ex' 'http://example.com/ns#'}, 47 | then will return: 'ex:t'. 48 | 49 | Optionally records the usage of that prefix in the used-atom." 50 | [iri flipped-ctx match-iris used-atom] 51 | (some 52 | (fn [iri-substr] 53 | (when (str/starts-with? iri iri-substr) ;; match 54 | (let [prefix (get flipped-ctx iri-substr) 55 | suffix (subs iri (count iri-substr))] 56 | (when used-atom 57 | (add-match-to-used-atom prefix iri-substr used-atom)) 58 | (if (keyword? prefix) 59 | (if (#{:vocab :base} prefix) 60 | (subs iri (count iri-substr)) 61 | (keyword (name prefix) suffix)) 62 | (str prefix ":" suffix))))) 63 | match-iris)) 64 | 65 | 66 | (defn- exact-iri-match 67 | "If the input iri is an exact match to a context value, 68 | e.g. the input iri is 'http://example.com/ns#t' 69 | with a context of: {'t' 'http://example.com/ns#t'}, 70 | then will return: 't'. 71 | 72 | Optionally records the usage of that prefix in the used-atom." 73 | [iri flipped-ctx used-atom] 74 | (when-let [exact (get flipped-ctx iri)] 75 | (when used-atom 76 | (add-match-to-used-atom exact iri used-atom)) 77 | exact)) 78 | 79 | 80 | (defn compact-fn 81 | "Returns a single arity function based on the provided context that will compact any string iri. 82 | 83 | Optionally, a second param, used-atom, can be supplied which captures all context items that were used. 84 | This is useful when a large context is present which only a small subset will be used, and you want to 85 | know which subset were used." 86 | ([context] (compact-fn context nil)) 87 | ([context used-atom] 88 | (let [flipped-ctx (reverse-context context) ;; flips context map 89 | match-iris (->> flipped-ctx 90 | keys 91 | (filter #(#{\/ \#} (last %))) ;; only match against iris ending with '#' or '/' 92 | (sort-by #(* -1 (count %))))] 93 | (fn [iri] 94 | (or (exact-iri-match iri flipped-ctx used-atom) 95 | (partial-iri-match iri flipped-ctx match-iris used-atom) 96 | iri))))) 97 | 98 | 99 | (defn compact 100 | "Goes through context and attempts to shorten iri if matches context, else returns original IRI. 101 | 102 | Uses query context format where context values have {:iri 'iri-here'}, so must already be parsed." 103 | [iri parsed-context-or-fn] 104 | (let [match-fn (if (fn? parsed-context-or-fn) 105 | parsed-context-or-fn 106 | (compact-fn parsed-context-or-fn))] 107 | (match-fn iri))) 108 | 109 | 110 | (comment 111 | (fluree.json-ld.context/parse ["https://flur.ee/ns/block" 112 | {:type-key "@type", 113 | "schema" {:id "http://schema.org/"}, 114 | "wiki" {:id "https://www.wikidata.org/wiki/"}}]) 115 | 116 | (compact "http://schema.org/name" (fluree.json-ld.context/parse ["https://flur.ee/ns/block" 117 | {:type-key "@type", 118 | "schema" {:id "http://schema.org/"}, 119 | "wiki" {:id "https://www.wikidata.org/wiki/"}}])) 120 | 121 | ) -------------------------------------------------------------------------------- /src/fluree/json_ld/impl/context.cljc: -------------------------------------------------------------------------------- 1 | (ns fluree.json-ld.impl.context 2 | (:require [fluree.json-ld.impl.iri :as iri] 3 | [fluree.json-ld.impl.util :refer [try-catchall]] 4 | [fluree.json-ld.impl.external :as external] 5 | [clojure.string :as str])) 6 | 7 | #?(:clj (set! *warn-on-reflection* true)) 8 | 9 | (declare parse) 10 | 11 | (defn keywordize-at-value 12 | "If a context key value starts with '@' (i.e. @type, @id), returns 13 | keywordized version of those keys (i.e. :type, :id)." 14 | [at-value] 15 | (if (and (string? at-value) (= \@ (first at-value))) 16 | (keyword (subs at-value 1)) 17 | at-value)) 18 | 19 | (defn vocab 20 | "Computes vocab prefix given provided base-context, context, & vocab" 21 | [base-context context vocab] 22 | (let [base (or (get context "@base") 23 | (get base-context :base))] 24 | (if (= "" vocab) ; empty string means use @base as @vocab 25 | (when base (iri/add-trailing-slash base)) 26 | (if (and base (not (iri/absolute? vocab))) 27 | ;; @vocab relative to @base 28 | (iri/join base vocab) 29 | (iri/add-trailing-slash vocab))))) 30 | 31 | (defn parse-compact-iri-val 32 | "A context's value may itself be a compact IRI which refers to 33 | another key in the original context map. 34 | 35 | If it is a compact IRI, attempts to resolve it, else returns original value 36 | 37 | i.e. with: 38 | {'nc' 'http://release.niem.gov/niem/niem-core/4.0/#' 39 | 'name' 'nc:PersonName'} 40 | we ultimately want 'name' to map to http://release.niem.gov/niem/niem-core/4.0/#PersonName" 41 | [orig-context base-context default-vocab compact-iri] 42 | (cond 43 | (str/includes? compact-iri ":") 44 | (or (when-let [[prefix suffix] (iri/parse-prefix compact-iri)] 45 | (when-let [full-prefix (or (get orig-context prefix) 46 | (get-in orig-context [prefix "@id"]) 47 | (get-in base-context [prefix :id]))] 48 | (str full-prefix suffix))) 49 | compact-iri) 50 | 51 | default-vocab 52 | (if (str/starts-with? compact-iri "@") 53 | compact-iri 54 | (str default-vocab compact-iri)) 55 | 56 | :else compact-iri)) 57 | 58 | 59 | (defn- recursively-get-id 60 | "@id values may reference other keys in the original context map, sometimes 61 | several layers deep. This attempts to get the deepest reference and returns it as the val. 62 | 63 | e.g. in the CLR: 64 | {'CompactJws': 'dtCompactJws' 65 | 'dtCompactJws': 'dtCompactJws' {'@id': 'clri:dtCompactJws', 66 | '@type': 'xsd:string'} 67 | ... } 68 | 69 | or: 70 | {'Address': 'dtAddress', 71 | 'dtAddress': 'clri:dtAddress' 72 | ... }" 73 | [compact-iri ctx-original] 74 | (let [compact-iri* (get ctx-original compact-iri)] 75 | (cond (= compact-iri* compact-iri) 76 | (throw (ex-info "A local context contains a term that has an invalid or missing IRI mapping" 77 | {:status 400 :error :json-ld/invalid-iri-mapping :context ctx-original})) 78 | compact-iri* 79 | (recur compact-iri* ctx-original) 80 | 81 | :else 82 | compact-iri))) 83 | 84 | (defn- assert-kw-string 85 | "Throws if provided value is not a keyword or string, original key provided for nicer error message" 86 | [k v] 87 | (if (or (string? v) (keyword? v)) 88 | v 89 | (throw (ex-info (str "Invalid @context value in json-ld. " k 90 | " must be a string value, provided: " v ".") 91 | {:status 400 92 | :error :json-ld/invalid-context})))) 93 | 94 | (defn- parse-value 95 | "Parses json-ld context value. If a map, iterates over keys." 96 | [ctx-key ctx-val ctx-original ctx-base externals] 97 | (let [default-vocab (when-let [vocab (get ctx-original "@vocab")] 98 | (or (get vocab "@id") vocab)) 99 | default-vocab* (when default-vocab 100 | (vocab ctx-base ctx-original default-vocab)) 101 | ctx-val* (if (string? ctx-val) 102 | (recursively-get-id ctx-val ctx-original) 103 | ctx-val)] 104 | (cond 105 | (string? ctx-val*) 106 | (let [iri-v (parse-compact-iri-val ctx-original ctx-base default-vocab* ctx-val*)] 107 | (cond-> {:id iri-v} 108 | (= "@type" iri-v) (assoc :type? true))) 109 | 110 | (map? ctx-val*) 111 | (let [map-val (reduce-kv 112 | (fn [acc k v] 113 | (let [k* (keywordize-at-value k)] 114 | (assoc acc k* (cond 115 | (= :type k*) 116 | (->> v 117 | (assert-kw-string k) 118 | (parse-compact-iri-val ctx-original ctx-base default-vocab*) 119 | keywordize-at-value) 120 | 121 | (#{:id :reverse} k*) 122 | (->> v 123 | (assert-kw-string k) 124 | (parse-compact-iri-val ctx-original ctx-base default-vocab*)) 125 | 126 | (= :context k*) 127 | (parse {} externals v) 128 | 129 | (= :container k*) 130 | (try-catchall 131 | (if (sequential? v) 132 | (mapv keywordize-at-value v) 133 | (keywordize-at-value v)) 134 | (catch e 135 | (throw (ex-info (str "@container values must be one or more strings that start with @. Provided: " v) 136 | {:status 400 :error :json-ld/invalid-context} e)))) 137 | 138 | :else v)))) 139 | {} ctx-val*)] 140 | ;; sometimes a context defines a compact-iri as the key and only includes @type - in this case we need to generate an @id 141 | (if (or (contains? map-val :id) 142 | (contains? map-val :reverse)) 143 | map-val 144 | (assoc map-val :id (parse-compact-iri-val ctx-original ctx-base default-vocab* ctx-key)))) 145 | 146 | :else 147 | (throw (ex-info (str "Invalid context provided. Context map values must be a scalars or map. " 148 | "Error at value: " ctx-val) 149 | {:status 400 :error :json-ld/invalid-context}))))) 150 | 151 | (defn copy-to-full-iri 152 | "When a compact IRI is used to set the default datatype (@type), 153 | the data may also use the full IRI. This copies the options to the 154 | full IRI such that the data can use either the compact or full IRI." 155 | [context {:keys [id] :as parsed-v}] 156 | ;; note if original context 'key' was already fully expanded, then 157 | ;; k = id and it just overwrites with same value - no need to do a check 158 | (assoc context id parsed-v)) 159 | 160 | (defn parse-map 161 | "Parses json-ld context and returns clojure map. 162 | If an already parsed base-context is provided, merges it into base-context. 163 | 164 | Each context term is a key, and each value a map with term details within. The maps include: 165 | :id - @id value - the IRI, or IRI substring for the context item 166 | :vocab - @vocab value - if using a default vocabulary (effectively a blank term). There 167 | can only be one vocab value for the returned context." 168 | [base-context externals context] 169 | (reduce-kv 170 | (fn [acc k v] 171 | (if (and (string? k) (= \@ (first k))) 172 | (let [kw (keyword (subs k 1)) 173 | v* (cond 174 | (= :vocab kw) 175 | (vocab base-context context v) 176 | 177 | (string? v) 178 | (keywordize-at-value v) 179 | 180 | :else v)] 181 | (assoc acc kw v*)) 182 | (let [parsed-v (parse-value k v context base-context externals)] 183 | (cond-> (assoc acc k parsed-v) 184 | (true? (:type? parsed-v)) (assoc :type-key k) 185 | (:type parsed-v) (copy-to-full-iri parsed-v))))) 186 | base-context context)) 187 | 188 | 189 | (defn parse 190 | "Parses json-ld context and returns clojure map. 191 | If an already parsed base-context is provided, merges it into base-context. 192 | 193 | Each context term is a key, and each value a map with term details within. The maps include: 194 | :id - @id value - the IRI, or IRI substring for the context item 195 | :vocab - @vocab value - if using a default vocabulary (effectively a blank term). There 196 | can only be one vocab value for the returned context. 197 | :type-key - The key @type is mapped to (default is @type). If context includes 198 | e.g. {'type' '@type'} then :type-key would be equal to 'type'. 199 | It is important to know @type values prior to parsing as context 200 | may include a sub-context specific to an @type - if those cannot be 201 | checked easily up front, parsing will be done with the wrong context 202 | (unless you are lucky and the @type is defined first)." 203 | ([context] (parse {} external/external-contexts context)) 204 | ([base-context context] (parse base-context external/external-contexts context)) 205 | ([base-context externals context] 206 | (let [active-context (if (contains? base-context :type-key) 207 | base-context 208 | ;; :type-key will be replaced while parsing if overridden by context 209 | {:type-key "@type"})] 210 | (cond 211 | ;; nil resets the context 212 | (nil? context) 213 | {} 214 | 215 | ;; assume either an external context, or a default vocab 216 | (string? context) 217 | (if (externals context) 218 | (merge active-context (external/context context)) 219 | (assoc active-context :vocab (iri/add-trailing-slash context))) 220 | 221 | (map? context) 222 | (if (contains? context "@context") 223 | ;; contexts, especially externally loaded, can have a single @context key with context embedded 224 | (parse active-context (get context "@context" externals)) 225 | (parse-map active-context externals context)) 226 | 227 | (sequential? context) 228 | (reduce (fn [active-context context] 229 | (parse active-context externals context)) 230 | active-context 231 | context) 232 | 233 | :else 234 | (throw (ex-info (str "Invalid json-ld context provided: " context) 235 | {:status 400 236 | :error :json-ld/invalid-context 237 | :context context})))))) 238 | 239 | (comment 240 | 241 | (parse nil 242 | ["https://ns.flur.ee/ledger/v1"]),) 243 | -------------------------------------------------------------------------------- /src/fluree/json_ld/impl/external.cljc: -------------------------------------------------------------------------------- 1 | (ns fluree.json-ld.impl.external 2 | (:require [fluree.json-ld.impl.iri :as iri] 3 | [fluree.json-ld.impl.util :as util] 4 | [clojure.string :as str]) 5 | (:refer-clojure :exclude [read]) 6 | #?(:cljs (:require-macros [fluree.json-ld.impl.external :refer [inline-files inline-json]]))) 7 | 8 | #?(:clj (set! *warn-on-reflection* true)) 9 | 10 | (def vocab->file {"https://schema.org/" "org.schema.edn" 11 | "http://schema.org/" "org.schema.edn" 12 | "http://www.w3.org/2002/07/owl#" "owl.edn" 13 | "http://www.w3.org/2000/01/rdf-schema#" "rdfs.edn" 14 | "http://www.w3.org/2004/02/skos/core#" "skos.edn" 15 | "http://purl.org/dc/terms/" "org.purl.dc.terms.edn" 16 | "https://w3id.org/openbadges#" "org.w3id.openbadges.edn" 17 | "https://purl.imsglobal.org/spec/clr/vocab#" "org.imsglobal.spec.clr.vocab.edn"}) 18 | 19 | (def context->file {"https://ns.flur.ee" 20 | {:source "contexts/fluree/v1.json" 21 | :parsed "contexts/fluree/v1.edn"} 22 | 23 | "https://ns.flur.ee/ledger/v1" 24 | {:source "contexts/fluree/ledger/v1.jsonld" 25 | :parsed "contexts/fluree/ledger/v1.edn"} 26 | 27 | "http://www.w3.org/ns/shacl" 28 | {:source "contexts/org/w3/www/ns/shacl/v1.jsonld" 29 | :parsed "contexts/org/w3/www/ns/shacl/v1.edn"} 30 | 31 | "https://purl.imsglobal.org/spec/clr/v1p0/context/clr_v1p0.jsonld" 32 | {:source "contexts/org/imsglobal/purl/spec/clr/v1p0/context/clr_v1p0.jsonld" 33 | :parsed "contexts/org/imsglobal/purl/spec/clr/v1p0/context/clr_v1p0.edn"} 34 | 35 | "https://www.w3.org/2018/credentials/v1" 36 | {:source "contexts/org/w3/www/2018/credentials/v1.jsonld" 37 | :parsed "contexts/org/w3/www/2018/credentials/v1.edn"} 38 | 39 | "https://www.w3.org/ns/did/v1" 40 | {:source "contexts/org/w3/www/ns/did/v1.jsonld" 41 | :parsed "contexts/org/w3/www/ns/did/v1.edn"} 42 | 43 | "https://w3id.org/did/v1" 44 | {:source "contexts/org/w3/www/ns/did/v1.jsonld" 45 | :parsed "contexts/org/w3/www/ns/did/v1.edn"} 46 | 47 | "https://w3id.org/security/v1" 48 | {:source "contexts/org/w3id/security/v1.jsonld" 49 | :parsed "contexts/org/w3id/security/v1.edn"} 50 | 51 | "https://w3id.org/security/v2" 52 | {:source "contexts/org/w3id/security/v2.jsonld" 53 | :parsed "contexts/org/w3id/security/v2.edn"} 54 | 55 | "https://schema.org" 56 | {:source "contexts/org/schema/latest.jsonld" 57 | :parsed "contexts/org/schema/latest.edn"} 58 | 59 | "https://geojson.org/geojson-ld/geojson-context.jsonld" 60 | {:source "contexts/org/geojson/geojson-ld/geojson-context.jsonld" 61 | :parsed "contexts/org/geojson/geojson-ld/geojson-context.edn"} 62 | }) 63 | 64 | ;; set of external context URLs that are available pre-parsed. 65 | (def external-contexts (set (keys context->file))) 66 | 67 | (def vocabs (->> vocab->file keys (sort-by count) reverse)) 68 | 69 | #?(:clj 70 | (defmacro inline-files 71 | "The classpath doesn't exist in javascript, so we need to inline all of our resources at 72 | compile time so they are available to js applications at runtime." 73 | [] 74 | (let [loaded-contexts (reduce (fn [l [_ {:keys [parsed]}]] 75 | (assoc l parsed (util/read-resource parsed))) 76 | {} 77 | context->file) 78 | loaded (reduce (fn [l [k file]] 79 | (assoc l k (util/read-resource file))) 80 | loaded-contexts 81 | vocab->file)] 82 | loaded))) 83 | 84 | #?(:clj 85 | (defmacro inline-json 86 | "The classpath doesn't exist in javascript, so we need to inline all of our resources at 87 | compile time so they are available to js applications at runtime." 88 | [] 89 | (reduce (fn [l [url {:keys [source]}]] 90 | (assoc l url (util/slurp-resource source))) 91 | {} 92 | context->file))) 93 | 94 | #?(:cljs 95 | (def inlined-files (inline-files))) 96 | #?(:cljs 97 | (def inlined-contexts (inline-json))) 98 | 99 | #?(:cljs 100 | (defn read-inlined-resource 101 | [k] 102 | (get inlined-files k))) 103 | 104 | (defn vocab 105 | "Loads an entire vocabulary file, i.e. https://schema.org" 106 | [iri] 107 | (-> (get vocab->file (iri/add-trailing-slash iri)) 108 | #?(:clj util/read-resource 109 | :cljs read-inlined-resource))) 110 | 111 | 112 | (defn iri 113 | "Loads a supported external context and returns parsed (edn) format. 114 | 115 | Currently will not execute an http request to load, only pre-parsed vocabularies 116 | that exist in the resources folder work. 117 | 118 | Only supported on CLJ" 119 | [iri] 120 | (some #(when (str/starts-with? iri %) 121 | (-> (vocab %) 122 | (get iri))) 123 | vocabs)) 124 | 125 | (defn context 126 | "JSON-ld @context can be an external .jsonld file, for which we have some locally. 127 | Not external HTTP requests happens from this library, however anyone can implement that independently. 128 | 129 | Returns nil if the context requested does not exist." 130 | [url] 131 | (some-> (get context->file url) 132 | :parsed 133 | #?(:clj util/read-resource 134 | :cljs read-inlined-resource))) 135 | -------------------------------------------------------------------------------- /src/fluree/json_ld/impl/iri.cljc: -------------------------------------------------------------------------------- 1 | (ns fluree.json-ld.impl.iri 2 | (:require [fluree.json-ld.impl.util :refer [try-catchall]] 3 | [clojure.string :as str])) 4 | 5 | #?(:clj (set! *warn-on-reflection* true)) 6 | 7 | (defn parse-compact-iri 8 | "Returns 3-tuple of [original-iri prefix suffix] if string looks like 9 | a compact IRI (i.e. xsd:string or schema:name), else nil. 10 | 11 | Compact IRI must have only one colon (:) and no have a slash before 12 | or immediately after the colon which ensures it isn't a URL (i.e. https://schema.org)." 13 | [x] 14 | (if (keyword? x) 15 | [x (keyword (namespace x)) (name x)] 16 | (if (= \: (first x)) 17 | [x ":" (subs x 1)] ;; prefix is ':' 18 | (re-matches #"([^:/]+):([^/:][^:]*)" x)))) 19 | 20 | (defn any-iri? 21 | "Returns true if string has a colon, indicating it is either a compact 22 | iri or full iri. 23 | 24 | Only to be used when a quick test is needed, not a thorough test." 25 | [x] 26 | (str/includes? x ":")) 27 | 28 | 29 | (defn add-trailing-slash 30 | "In certain circumstances we want context partial IRIs to end in either a '/' or '#'. 31 | If it ends in neither, we assume it was meant to end in '/' and add it to the end. 32 | 33 | i.e. if provided https://schema.org, we'll change it to https://schema.org/" 34 | [partial-iri] 35 | (if (#{\/ \#} (last partial-iri)) 36 | partial-iri 37 | (str partial-iri "/"))) 38 | 39 | 40 | (defn parse-prefix 41 | [s] 42 | (try-catchall 43 | (when-let [[_ prefix suffix] (parse-compact-iri s)] 44 | [prefix suffix]) 45 | (catch e (throw (ex-info (str "Error attempting to parse iri: " s) 46 | {:status 400 47 | :error :json-ld/invalid-iri} 48 | e))))) 49 | 50 | (defn join 51 | "Returns an IRI string for relative IRI `ri` relative to absolute `base` IRI. 52 | Makes no attempt to correct trailing / leading character errors, so make sure 53 | `base` ends in / or # and `ri` begins with neither." 54 | [base ri] 55 | (str base ri)) 56 | 57 | (defn absolute? 58 | "A very basic check if an IRI is absolute. NB: A false result does not imply 59 | that it is a valid relative IRI." 60 | [iri] 61 | (str/includes? iri ":")) 62 | -------------------------------------------------------------------------------- /src/fluree/json_ld/impl/normalize.cljc: -------------------------------------------------------------------------------- 1 | (ns fluree.json-ld.impl.normalize 2 | (:require [clojure.string :as str])) 3 | 4 | ;; normalizing json-ld for hashing, cryptographic signatures, etc. 5 | ;; test against https://github.com/digitalbazaar/jsonld.js as baseline 6 | 7 | ;; basic normalization per JSON Canonicalization Scheme https://datatracker.ietf.org/doc/html/rfc8785 8 | 9 | ;; NOTE - this work is to be done! 10 | 11 | (def exp-str->exponent 12 | {"1" 1 13 | "2" 2 14 | "3" 3 15 | "4" 4 16 | "5" 5 17 | "6" 6 18 | "7" 7 19 | "8" 8}) 20 | 21 | (defn- remove-trailing-decimal 22 | "For numbers that have decimals, if the decimal is '.0' then remove it" 23 | [number-as-str] 24 | (if (str/ends-with? number-as-str ".0") 25 | (subs number-as-str 0 (- (count number-as-str) 2)) 26 | number-as-str)) 27 | 28 | 29 | (defn- move-decimal 30 | "Converts an exponent string representation into a standard number 31 | Used for smaller exponents that the standardization looks to keep as a 32 | regular number value. 33 | 34 | e.g. 3.333333333333333E8 should instead return 333333333.3333333 35 | 36 | Takes the number portion of the exponent as the first argument, and 37 | an exponent integer as a second. Using the above example the args would be: 38 | ['3.333333333333333' 8]" 39 | [number-as-str exponent] 40 | (let [[pre-decimal post-decimal] (str/split number-as-str #"\.")] 41 | (str pre-decimal (subs post-decimal 0 exponent) "." (subs post-decimal exponent)))) 42 | 43 | 44 | (declare basic-normalize-seq) 45 | 46 | (defmulti basic-normalize (fn [node] 47 | (cond 48 | (map? node) :map 49 | (sequential? node) :seq 50 | (nil? node) :nil 51 | (number? node) :number 52 | :else :default))) 53 | 54 | (defmethod basic-normalize :map 55 | [node] 56 | (let [sorted (sort-by #(-> % first str) (into [] node)) 57 | ser-nodes (mapv (fn [[k v]] 58 | (str "\"" k "\":" (basic-normalize v))) 59 | sorted)] 60 | (str "{" (str/join "," ser-nodes) "}"))) 61 | 62 | (defmethod basic-normalize :seq 63 | [node] 64 | (let [ser-items (mapv basic-normalize node)] 65 | (str "[" (str/join "," ser-items) "]"))) 66 | 67 | (defmethod basic-normalize :nil 68 | [node] 69 | "null") 70 | 71 | (defmethod basic-normalize :number 72 | [number] 73 | (let [n-str (str number)] 74 | (if (str/includes? n-str "E") 75 | (let [[num exp] (str/split n-str #"E")] 76 | (cond 77 | (str/starts-with? exp "-") 78 | (str (remove-trailing-decimal num) "e" exp) 79 | 80 | (get exp-str->exponent exp) 81 | (move-decimal num (get exp-str->exponent exp)) 82 | 83 | :else 84 | (str (remove-trailing-decimal num) "e+" exp))) 85 | (remove-trailing-decimal n-str)))) 86 | 87 | (defmethod basic-normalize :default 88 | [node] 89 | (pr-str node)) 90 | 91 | 92 | 93 | (defn normalize 94 | ([json-ld] (normalize json-ld {:algorithm :basic 95 | :format :application/json})) 96 | ([json-ld {:keys [algorithm format] :or {algorithm :URDNA2015 97 | format :application/n-quads}}] 98 | (when (not= algorithm :basic) 99 | (throw (ex-info (str "Algorithm: " algorithm " not yet implemented!") 100 | {:status 400 :error :json-ld/invalid-normalization}))) 101 | (when (not= format :application/json) 102 | (throw (ex-info (str "Format: " format " not yet implemented!") 103 | {:status 400 :error :json-ld/invalid-normalization}))) 104 | (basic-normalize json-ld))) 105 | -------------------------------------------------------------------------------- /src/fluree/json_ld/impl/util.cljc: -------------------------------------------------------------------------------- 1 | (ns fluree.json-ld.impl.util 2 | (:require #?(:clj [clojure.java.io :as io]) 3 | #?(:clj [clojure.edn :as edn])) 4 | #?(:cljs (:require-macros [fluree.json-ld.impl.util :refer [try-catchall if-cljs]]))) 5 | 6 | #?(:clj (set! *warn-on-reflection* true)) 7 | 8 | #?(:clj (defn cljs-env? 9 | "Take the &env from a macro, and tell whether we are expanding into cljs." 10 | [env] 11 | (boolean (:ns env)))) 12 | 13 | #?(:clj 14 | (defmacro if-cljs 15 | "Return then if we are generating cljs code and else for Clojure code. 16 | https://groups.google.com/d/msg/clojurescript/iBY5HaQda4A/w1lAQi9_AwsJ" 17 | [then else] 18 | (if (cljs-env? &env) then else))) 19 | 20 | #?(:clj 21 | (defmacro try-catchall 22 | "A cross-platform variant of try-catch that catches all exceptions. 23 | Does not (yet) support finally, and does not need or want an exception class." 24 | [& body] 25 | (let [try-body (butlast body) 26 | [catch sym & catch-body :as catch-form] (last body)] 27 | (assert (= catch 'catch)) 28 | (assert (symbol? sym)) 29 | `(if-cljs 30 | (try ~@try-body (~'catch js/Object ~sym ~@catch-body)) 31 | (try ~@try-body (~'catch Throwable ~sym ~@catch-body)))))) 32 | 33 | (defn sequential 34 | "Takes any value and if not sequential?, wraps it in a vector." 35 | [x] 36 | (if (sequential? x) 37 | x 38 | [x])) 39 | 40 | (defn slurp-resource 41 | [filename] 42 | #?(:cljs (throw (ex-info (str "Loading external resources is not yet supported in Javascript.") 43 | {:status 400 :error :json-ld/external-resource})) 44 | :clj (try 45 | (some-> filename 46 | io/resource 47 | slurp) 48 | (catch Exception e 49 | (throw (ex-info 50 | (str "Invalid IRI, unable to read vocabulary from: " filename) 51 | {:status 400 :error :json-ld/external-resource} 52 | e)))))) 53 | #?(:clj 54 | (defn read-resource 55 | [filename] 56 | (edn/read-string (slurp-resource filename)))) 57 | 58 | (comment 59 | (try-catchall 60 | (/ 1 0) 61 | (catch e 62 | (println e))) 63 | 64 | (if-cljs :cljs :clj) 65 | :cljs 66 | :clj 67 | 68 | nil 69 | nil 70 | 71 | #_(read-resource "foo") 72 | ) 73 | -------------------------------------------------------------------------------- /src/fluree/json_ld/processor/api.clj: -------------------------------------------------------------------------------- 1 | (ns fluree.json-ld.processor.api 2 | (:refer-clojure :exclude [flatten]) 3 | (:require [jsonista.core :as json] 4 | [fluree.json-ld.impl.external :as external] 5 | [clojure.java.io :as io]) 6 | (:import (com.apicatalog.jsonld JsonLd JsonLdError JsonLdErrorCode) 7 | (com.apicatalog.jsonld.document JsonDocument) 8 | (com.apicatalog.jsonld.loader DocumentLoader FileLoader DocumentLoaderOptions) 9 | (com.apicatalog.rdf RdfNQuad) 10 | (io.setl.rdf.normalization RdfNormalize) 11 | (java.net URI) 12 | (java.io StringReader))) 13 | 14 | (set! *warn-on-reflection* true) 15 | 16 | (defprotocol Parseable 17 | (parsed [x])) 18 | 19 | (extend-protocol Parseable 20 | jakarta.json.EmptyArray 21 | (parsed [x] []) 22 | ;; JsonArray 23 | org.glassfish.json.JsonArrayBuilderImpl$JsonArrayImpl 24 | (parsed [x] 25 | (into [] (map parsed x))) 26 | ;; JsonObject 27 | org.glassfish.json.JsonObjectBuilderImpl$JsonObjectImpl 28 | (parsed [x] 29 | (into {} (map (fn [[k v]] [k (parsed v)]) x))) 30 | org.glassfish.json.JsonNumberImpl 31 | ;; JsonNumber 32 | (parsed [x] 33 | (if (.isIntegral x) 34 | (.longValue x) 35 | (.doubleValue x))) 36 | ;; JsonString 37 | org.glassfish.json.JsonStringImpl 38 | (parsed [x] 39 | (.getString x)) 40 | 41 | jakarta.json.JsonValueImpl 42 | (parsed [x] 43 | (case (.toString x) 44 | "true" true 45 | "false" false 46 | "null" nil))) 47 | 48 | (defn- ->json-document 49 | ^JsonDocument [edn] 50 | (-> edn 51 | (json/write-value-as-string) 52 | (StringReader.) 53 | (JsonDocument/of))) 54 | 55 | (defn ->document 56 | "Takes a document-loader, which takes a url and options and returns a json string 57 | context document (must have an \"@context\" key with a context as its value). 58 | 59 | document-loader: [url options] => json-string 60 | " 61 | [document-loader url options] 62 | (let [url-string (.toString ^URI url)] 63 | (try 64 | (let [json-string (document-loader url-string options)] 65 | (JsonDocument/of (io/input-stream (.getBytes ^String json-string)))) 66 | (catch Exception e 67 | (throw (JsonLdError. JsonLdErrorCode/LOADING_REMOTE_CONTEXT_FAILED 68 | (str "Unable to load context: " url-string))))))) 69 | 70 | (defrecord PluggableLoader [document-loader] 71 | DocumentLoader 72 | (loadDocument [_ url options] 73 | (->document document-loader url options))) 74 | 75 | (defn static-loader 76 | [url options] 77 | (if-let [{path :source} (external/context->file url)] 78 | (slurp (io/resource path)) 79 | (throw (ex-info (str "Unable to load static context: " url) 80 | {:url url})))) 81 | 82 | (defn expand 83 | ([json-ld] 84 | (expand json-ld {:document-loader static-loader})) 85 | ([json-ld opts] 86 | (-> (->json-document json-ld) 87 | (JsonLd/expand) 88 | (.loader ^DocumentLoader (->PluggableLoader (:document-loader opts))) 89 | (.get) 90 | (parsed)))) 91 | 92 | (defn compact 93 | ([json-ld context] 94 | (compact json-ld context {:document-loader static-loader})) 95 | ([json-ld context opts] 96 | (-> (->json-document json-ld) 97 | (JsonLd/compact (->json-document context)) 98 | (.loader ^DocumentLoader (->PluggableLoader (:document-loader opts))) 99 | (.get) 100 | (parsed)))) 101 | 102 | (defn flatten 103 | ([json-ld] 104 | (flatten json-ld {:document-loader static-loader})) 105 | ([json-ld opts] 106 | (-> (->json-document json-ld) 107 | (JsonLd/flatten) 108 | (.loader ^DocumentLoader (->PluggableLoader (:document-loader opts))) 109 | (.get) 110 | (parsed)))) 111 | 112 | (defn- ->statement 113 | [^RdfNQuad quad] 114 | (str (let [subject (.getSubject quad)] 115 | (if (.isIRI subject) 116 | (str "<" (.toString subject) ">") 117 | (.toString subject))) 118 | " " 119 | (let [predicate (.getPredicate quad)] 120 | (if (.isIRI predicate) 121 | (str "<" (.toString predicate) ">") 122 | (.toString predicate))) 123 | " " 124 | (let [object (.getObject quad)] 125 | (cond (.isIRI object) 126 | (str "<" (.toString object) ">") 127 | (.isLiteral object) 128 | (let [literal (.asLiteral object) 129 | datatype (.getDatatype literal) 130 | lang (.getLanguage literal) 131 | value (.getValue object)] 132 | (str "\"" value "\"" 133 | (if (.isPresent lang) 134 | (str "@" (.get lang)) 135 | (when (not= "http://www.w3.org/2001/XMLSchema#string" datatype) 136 | (str "^^<" datatype ">"))))) 137 | :else ; blank node 138 | (.toString object))) 139 | " .")) 140 | 141 | (defn to-rdf 142 | ([json-ld] 143 | (to-rdf json-ld {:document-loader static-loader})) 144 | ([json-ld opts] 145 | (-> (->json-document json-ld) 146 | (JsonLd/toRdf) 147 | (.loader ^DocumentLoader (->PluggableLoader (:document-loader opts))) 148 | (.get) 149 | (.toList) 150 | (->> (reduce (fn [doc quad] (str doc (->statement quad) "\n")) ""))))) 151 | 152 | (defn canonize 153 | ([json-ld] 154 | (canonize json-ld {:document-loader static-loader})) 155 | ([json-ld opts] 156 | (-> (->json-document json-ld) 157 | (JsonLd/toRdf) 158 | (.loader ^DocumentLoader (->PluggableLoader (:document-loader opts))) 159 | (.get) 160 | (RdfNormalize/normalize) 161 | (.toList) 162 | (->> (reduce (fn [doc quad] (str doc (->statement quad) "\n")) ""))))) 163 | 164 | (comment 165 | ;; These work up to translating the resulting json-ld back into edn 166 | #_(defn- ->rdf-document 167 | [nquads] 168 | (-> nquads 169 | (StringReader.) 170 | (RdfDocument/of))) 171 | 172 | #_(defn from-rdf 173 | [n-quads] 174 | ;; TODO: figure out parsing to edn 175 | (parsed (.get (JsonLd/fromRdf ^RdfDocument (->rdf-document n-quads))))) 176 | ) 177 | -------------------------------------------------------------------------------- /src/fluree/json_ld/processor/api.cljs: -------------------------------------------------------------------------------- 1 | (ns fluree.json-ld.processor.api 2 | (:refer-clojure :exclude [flatten]) 3 | (:require ["jsonld" :as jldjs] 4 | [fluree.json-ld.impl.external :as external])) 5 | 6 | (defn pluggable-loader 7 | "Takes a document-loader, which takes a url and options and returns a json string 8 | context document (must have an \"@context\" key with a context as its value). 9 | 10 | document-loader: [url options] => json-string 11 | " 12 | [document-loader] 13 | (fn [url options] 14 | (js/Promise. 15 | (fn [resolve reject] 16 | (try 17 | (let [json-string (document-loader url options)] 18 | (resolve #js{"contextUrl" nil, "document" json-string, "documentUrl" url})) 19 | (catch js/Error e 20 | (reject (throw #js{"name" "jsonld.LoadDocumentError" 21 | "message" (str "Unable to load static context: " url) 22 | "details" {"code" "loading remote context failed" 23 | "url" url}})))))))) 24 | 25 | (defn static-loader 26 | [url options] 27 | (get external/inlined-contexts url)) 28 | 29 | (defn compact 30 | ([json-ld context] 31 | (compact json-ld context {:document-loader static-loader})) 32 | ([json-ld context opts] 33 | (-> json-ld 34 | (clj->js) 35 | (jldjs/compact (clj->js context) #js{"documentLoader" (pluggable-loader (:document-loader opts))}) 36 | (.then (fn [result] (js->clj result)))))) 37 | 38 | (defn expand 39 | ([json-ld] 40 | (expand json-ld {:document-loader static-loader})) 41 | ([json-ld opts] 42 | (-> json-ld 43 | (clj->js) 44 | (jldjs/expand #js{"documentLoader" (pluggable-loader (:document-loader opts))}) 45 | (.then (fn [result] (js->clj result)))))) 46 | 47 | (defn flatten 48 | ([json-ld] 49 | (flatten json-ld {:document-loader static-loader})) 50 | ([json-ld opts] 51 | (-> json-ld 52 | (clj->js) 53 | (jldjs/flatten #js{"documentLoader" (pluggable-loader (:document-loader opts))}) 54 | (.then (fn [result] (js->clj result)))))) 55 | 56 | (defn from-rdf 57 | ([n-quads] 58 | (from-rdf n-quads {:document-loader static-loader})) 59 | ([n-quads opts] 60 | (-> n-quads 61 | (clj->js) 62 | (jldjs/fromRDF #js{"format" "application/n-quads" 63 | "documentLoader" (pluggable-loader (:document-loader opts))}) 64 | (.then (fn [result] (js->clj result)))))) 65 | 66 | (defn to-rdf 67 | ([json-ld] 68 | (to-rdf json-ld {:document-loader static-loader})) 69 | ([json-ld opts] 70 | (-> json-ld 71 | (clj->js) 72 | (jldjs/expand #js{"documentLoader" (pluggable-loader (:document-loader opts))}) 73 | (.then (fn [expanded] (jldjs/toRDF expanded #js{"format" "application/n-quads"})))))) 74 | 75 | (defn canonize 76 | ([json-ld] 77 | (canonize json-ld {:document-loader static-loader})) 78 | ([json-ld opts] 79 | (-> (to-rdf json-ld opts) 80 | (.then (fn [rdf] 81 | (jldjs/canonize rdf #js {"algorithm" "URDNA2015" "inputFormat" "application/n-quads"})))))) 82 | -------------------------------------------------------------------------------- /test/fluree/json_ld/impl/compact_test.cljc: -------------------------------------------------------------------------------- 1 | (ns fluree.json-ld.impl.compact-test 2 | (:require #?(:clj [clojure.test :as t :refer [deftest testing is]] 3 | :cljs [cljs.test :as t :refer [deftest testing is] :include-macros true]) 4 | [fluree.json-ld.impl.compact :as compact] 5 | [fluree.json-ld :as jsonld])) 6 | 7 | (deftest compacting-iri 8 | (testing "Compacting a string IRI with context in various forms" 9 | (let [map-ctx (jsonld/parse-context {"schema" "http://schema.org/" 10 | "REPLACE" "http://schema.org/Person" 11 | "x" "schema:x"}) 12 | str-ctx (jsonld/parse-context "https://schema.org")] 13 | (is (= "x" (compact/compact "http://schema.org/x" map-ctx))) 14 | (is (= "schema:xyz" (compact/compact "http://schema.org/xyz" map-ctx))) 15 | (is (= "REPLACE" (compact/compact "http://schema.org/Person" map-ctx))) 16 | (is (= "name" (compact/compact "http://schema.org/name" str-ctx))) 17 | 18 | ;; not a match, should return unaltered iri 19 | (is (= "schemas" (compact/compact "schemas" map-ctx))) 20 | (is (= "http://example.org/ns#blah" (compact/compact "http://example.org/ns#blah" str-ctx))) 21 | (is (= "http://example.org/ns#blah" (compact/compact "http://example.org/ns#blah" map-ctx))))) 22 | 23 | (testing "A nil context clears the context" 24 | (let [cleared-ctx (jsonld/parse-context [{"schema" "http://schema.org/" 25 | "REPLACE" "http://schema.org/Person" 26 | "x" "schema:x"} 27 | nil])] 28 | (is (= "http://schema.org/x" (compact/compact "http://schema.org/x" cleared-ctx))) 29 | (is (= "http://schema.org/xyz" (compact/compact "http://schema.org/xyz" cleared-ctx))) 30 | (is (= "http://schema.org/Person" (compact/compact "http://schema.org/Person" cleared-ctx)))))) 31 | 32 | 33 | (deftest compacting-function 34 | (testing "Generating a compacting function produces expected results" 35 | (let [map-ctx (jsonld/parse-context {"schema" "https://schema.org/" 36 | "REPLACE" "https://schema.org/Person"}) 37 | compact-fn (compact/compact-fn map-ctx)] 38 | 39 | (is (= "schema:name" (compact-fn "https://schema.org/name"))) 40 | (is (= "REPLACE" (compact-fn "https://schema.org/Person"))) 41 | (is (= "http://example.org/ns#blah" (compact-fn "http://example.org/ns#blah"))))) 42 | 43 | (testing "Generating a compacting function with an atom returns used context items" 44 | (let [map-ctx (jsonld/parse-context {"schema" "http://schema.org/" 45 | "REPLACE" "http://schema.org/Person"}) 46 | used-atom (atom {}) 47 | compact-fn (compact/compact-fn map-ctx used-atom)] 48 | 49 | (is (= "schema:name" (compact-fn "http://schema.org/name"))) 50 | (is (= {"schema" "http://schema.org/"} 51 | @used-atom)) 52 | (is (= "REPLACE" (compact-fn "http://schema.org/Person"))) 53 | (is (= {"schema" "http://schema.org/" 54 | "REPLACE" "http://schema.org/Person"} 55 | @used-atom)) 56 | (is (= "http://example.org/ns#blah" (compact-fn "http://example.org/ns#blah"))) 57 | (is (= {"schema" "http://schema.org/" 58 | "REPLACE" "http://schema.org/Person"} 59 | @used-atom))))) 60 | 61 | 62 | (deftest compact-fn-for-compact 63 | (testing "A compacting function can optionally be supplied as second param to compact" 64 | (let [map-ctx (jsonld/parse-context {"schema" "https://schema.org/" 65 | "REPLACE" "https://schema.org/Person"}) 66 | compact-fn (compact/compact-fn map-ctx)] 67 | (is (= "schema:name" (compact/compact "https://schema.org/name" compact-fn))) 68 | (is (= "REPLACE" (compact/compact "https://schema.org/Person" compact-fn))) 69 | (is (= "http://example.org/ns#blah" (compact/compact "http://example.org/ns#blah" compact-fn)))))) 70 | 71 | 72 | (deftest compact-keyword-context 73 | (testing "When Clojure keywords used in context, properly compact." 74 | (let [map-ctx (jsonld/parse-context {:schema "https://schema.org/" 75 | :replace "https://schema.org/Person"}) 76 | compact-fn (compact/compact-fn map-ctx)] 77 | (is (= :schema/name (compact/compact "https://schema.org/name" compact-fn))) 78 | (is (= :replace (compact/compact "https://schema.org/Person" compact-fn))) 79 | (is (= "http://example.org/ns#blah" (compact/compact "http://example.org/ns#blah" compact-fn)))))) 80 | -------------------------------------------------------------------------------- /test/fluree/json_ld/impl/context_test.cljc: -------------------------------------------------------------------------------- 1 | (ns fluree.json-ld.impl.context-test 2 | (:require #?(:clj [clojure.test :as t :refer [deftest testing is]] 3 | :cljs [cljs.test :as t :refer [deftest testing is] :include-macros true]) 4 | [fluree.json-ld.impl.context :as context])) 5 | 6 | 7 | (deftest default-vocabularies 8 | (testing "An explicitly defined default vocabulary with @vocab" 9 | (is (= (context/parse {"@vocab" "https://schema.org/"}) 10 | {:type-key "@type" 11 | :vocab "https://schema.org/"}))) 12 | 13 | (testing "References to default vocabulary should be concatenated" 14 | (is (= (context/parse {"@vocab" "https://schema.org/" 15 | "reverseRef" {"@reverse" "isBasedOn"} 16 | "explicit" "name" 17 | "dontTouch" "https://example.com/ns#42" 18 | "id" "@id"}) 19 | {:type-key "@type" 20 | :vocab "https://schema.org/" 21 | "reverseRef" {:reverse "https://schema.org/isBasedOn"} 22 | "explicit" {:id "https://schema.org/name"} 23 | "dontTouch" {:id "https://example.com/ns#42"} 24 | "id" {:id "@id"}})))) 25 | 26 | 27 | (deftest map-context-parsing 28 | (testing "Context map parsing" 29 | 30 | ;; string based context 31 | (is (= (context/parse {"owl" "http://www.w3.org/2002/07/owl#", 32 | "ex" "http://example.org/ns#"}) 33 | {:type-key "@type" 34 | "owl" {:id "http://www.w3.org/2002/07/owl#"} 35 | "ex" {:id "http://example.org/ns#"}})) 36 | 37 | 38 | ;; keywords are retained 39 | (is (= (context/parse {:owl "http://www.w3.org/2002/07/owl#", 40 | :ex "http://example.org/ns#"}) 41 | {:type-key "@type" 42 | :owl {:id "http://www.w3.org/2002/07/owl#"} 43 | :ex {:id "http://example.org/ns#"}})))) 44 | 45 | 46 | (deftest dependent-context 47 | (testing "Some contexts use compact IRIs defined in their own document" 48 | (testing "One level deep" 49 | (is (= (context/parse {"nc" "http://release.niem.gov/niem/niem-core/4.0/#", 50 | "name" "nc:PersonName"}) 51 | {:type-key "@type" 52 | "nc" {:id "http://release.niem.gov/niem/niem-core/4.0/#"} 53 | "name" {:id "http://release.niem.gov/niem/niem-core/4.0/#PersonName"}}))) 54 | (testing "Two levels deep" 55 | ;; from CLR vocabulary 56 | (is (= (context/parse {"clri" "https://purl.imsglobal.org/spec/clr/vocab#" 57 | "Address" "dtAddress", 58 | "dtAddress" "clri:dtAddress"}) 59 | {:type-key "@type" 60 | "Address" {:id "https://purl.imsglobal.org/spec/clr/vocab#dtAddress"} 61 | "clri" {:id "https://purl.imsglobal.org/spec/clr/vocab#"} 62 | "dtAddress" {:id "https://purl.imsglobal.org/spec/clr/vocab#dtAddress"}}))) 63 | (testing "Two levels deep with map val" 64 | ;; from CLR vocabulary 65 | (is (= (context/parse {"clri" "https://purl.imsglobal.org/spec/clr/vocab#" 66 | "xsd" "http://www.w3.org/2001/XMLSchema#" 67 | "UUID" "dtUUID" 68 | "dtUUID" {"@id" "clri:dtUUID", 69 | "@type" "xsd:string"}}) 70 | {:type-key "@type" 71 | "UUID" {:id "https://purl.imsglobal.org/spec/clr/vocab#dtUUID" 72 | :type "http://www.w3.org/2001/XMLSchema#string"} 73 | "clri" {:id "https://purl.imsglobal.org/spec/clr/vocab#"} 74 | "xsd" {:id "http://www.w3.org/2001/XMLSchema#"} 75 | "dtUUID" {:id "https://purl.imsglobal.org/spec/clr/vocab#dtUUID" 76 | :type "http://www.w3.org/2001/XMLSchema#string"} 77 | "https://purl.imsglobal.org/spec/clr/vocab#dtUUID" 78 | {:id "https://purl.imsglobal.org/spec/clr/vocab#dtUUID" 79 | :type "http://www.w3.org/2001/XMLSchema#string"}}))))) 80 | 81 | 82 | (deftest multiple-contexts 83 | (testing "Context map parsing" 84 | (is (= {:type-key "@type" 85 | "schema" {:id "http://schema.org/"} 86 | "owl" {:id "http://www.w3.org/2002/07/owl#"} 87 | "ex" {:id "http://example.org/ns#"}} 88 | (context/parse [{"schema" "http://schema.org/"}, 89 | {"owl" "http://www.w3.org/2002/07/owl#", 90 | "ex" "http://example.org/ns#"}])))) 91 | 92 | (testing "A second context may rely on definitions in the first" 93 | ;; this scenario happened with https://w3id.org/security/v1 -> https://w3id.org/security/v2 94 | (is (= {:type-key "@type" 95 | "sec" {:id "https://w3id.org/security#"}, 96 | "EcdsaSecp256k1VerificationKey2019" {:id "https://w3id.org/security#EcdsaSecp256k1VerificationKey2019"}} 97 | (context/parse [{"sec" "https://w3id.org/security#"} 98 | {"EcdsaSecp256k1VerificationKey2019" "sec:EcdsaSecp256k1VerificationKey2019"}])))) 99 | (testing "A nil context empties the context" 100 | (let [parsed {:type-key "@type", "sec" {:id "https://w3id.org/security#"}}] 101 | (is (= parsed 102 | (context/parse {"sec" "https://w3id.org/security#"})) 103 | "a parsed context") 104 | (is (= parsed 105 | (context/parse parsed {})) 106 | "an unmodified parsed context") 107 | (is (= {} 108 | (context/parse parsed nil)) 109 | "an empty context")))) 110 | 111 | 112 | (deftest nested-context-details 113 | (testing "Context keys with map values." 114 | 115 | ;; custom full iri with type defined 116 | (is (= (context/parse {"schema" "http://schema.org/", 117 | "customScalar" {"@id" "http://schema.org/name" 118 | "@type" "http://schema.org/Text"}}) 119 | {:type-key "@type" 120 | "schema" {:id "http://schema.org/"} 121 | "customScalar" {:id "http://schema.org/name" 122 | :type "http://schema.org/Text"} 123 | "http://schema.org/name" 124 | {:id "http://schema.org/name" 125 | :type "http://schema.org/Text"}})) 126 | 127 | (is (= (context/parse {"schema" "http://schema.org/", 128 | "customClass" {"@id" "schema:Book" 129 | "@type" "schema:CreativeWork"}}) 130 | {:type-key "@type" 131 | "schema" {:id "http://schema.org/"} 132 | "customClass" {:id "http://schema.org/Book" 133 | :type "http://schema.org/CreativeWork"} 134 | "http://schema.org/Book" 135 | {:id "http://schema.org/Book" 136 | :type "http://schema.org/CreativeWork"}})))) 137 | 138 | 139 | (deftest reverse-refs 140 | (testing "Reverse refs using full IRI" 141 | (is (= (context/parse {"@vocab" "http://schema.org/" 142 | "title" "http://schema.org/titleEIDR" 143 | "derivedWorks" {"@reverse" "http://schema.org/isBasedOn"}}) 144 | {:type-key "@type" 145 | :vocab "http://schema.org/", 146 | "title" {:id "http://schema.org/titleEIDR"}, 147 | "derivedWorks" {:reverse "http://schema.org/isBasedOn"}}))) 148 | 149 | (testing "Reverse refs with compact-iri" 150 | (is (= (context/parse {"schema" "http://schema.org/" 151 | "title" "schema:titleEIDR" 152 | "derivedWorks" {"@reverse" "schema:isBasedOn"}}) 153 | {:type-key "@type" 154 | "schema" {:id "http://schema.org/"}, 155 | "title" {:id "http://schema.org/titleEIDR"}, 156 | "derivedWorks" {:reverse "http://schema.org/isBasedOn"}})))) 157 | 158 | 159 | (deftest type-only 160 | (testing "A context map's value can include only @type and we must infer @id" 161 | (is (= (context/parse {"ical" "http://www.w3.org/2002/12/cal/ical#", 162 | "xsd" "http://www.w3.org/2001/XMLSchema#", 163 | "ical:dtstart" {"@type" "xsd:dateTime"}}) 164 | {:type-key "@type" 165 | "ical" {:id "http://www.w3.org/2002/12/cal/ical#"}, 166 | "xsd" {:id "http://www.w3.org/2001/XMLSchema#"}, 167 | "ical:dtstart" {:type "http://www.w3.org/2001/XMLSchema#dateTime", 168 | :id "http://www.w3.org/2002/12/cal/ical#dtstart"} 169 | "http://www.w3.org/2002/12/cal/ical#dtstart" 170 | {:type "http://www.w3.org/2001/XMLSchema#dateTime" 171 | :id "http://www.w3.org/2002/12/cal/ical#dtstart"}})))) 172 | 173 | (deftest blank-vocab 174 | (testing "An empty string @vocab should default to @base value." 175 | (is (= (context/parse {"@base" "https://hub.flur.ee/some/ledger/" 176 | "@vocab" ""}) 177 | {:type-key "@type" 178 | :base "https://hub.flur.ee/some/ledger/" 179 | :vocab "https://hub.flur.ee/some/ledger/"})))) 180 | 181 | (deftest metadata-parses 182 | (testing "@protected and @version properly parses" 183 | (is (= (context/parse {"@version" 1.1, 184 | "@protected" true 185 | "schema" "http://schema.org/"}) 186 | {:type-key "@type" 187 | :version 1.1 188 | :protected true 189 | "schema" {:id "http://schema.org/"}})))) 190 | 191 | (deftest containers-parse 192 | (testing "An @container value properly parses" 193 | (is (= (context/parse {"schema" "http://schema.org/" 194 | "post" {"@id" "schema:blogPost", 195 | "@container" "@set"}}) 196 | {:type-key "@type" 197 | "schema" {:id "http://schema.org/"} 198 | "post" {:id "http://schema.org/blogPost" 199 | :container :set}}))) 200 | (testing "Multiple @container values are allowed" 201 | (is (= (context/parse {"schema" "http://schema.org/" 202 | "post" {"@id" "schema:blogPost", 203 | "@container" ["@index" "@set"]}}) 204 | {:type-key "@type" 205 | "schema" {:id "http://schema.org/"} 206 | "post" {:id "http://schema.org/blogPost" 207 | :container [:index :set]}})))) 208 | 209 | (deftest keyword-context 210 | (testing "Using Clojure keywords in contexts" 211 | (is (= (context/parse {:schema "http://schema.org/"}) 212 | {:type-key "@type" 213 | :schema {:id "http://schema.org/"}})) 214 | 215 | (is (= (context/parse {:vocab "http://schema.org/"}) 216 | {:type-key "@type" 217 | :vocab {:id "http://schema.org/"}})) 218 | 219 | (is (= (context/parse {:id "@id" 220 | :type "@type" 221 | :schema "http://schema.org/"}) 222 | {:type-key :type 223 | :id {:id "@id"} 224 | :type {:id "@type", :type? true} 225 | :schema {:id "http://schema.org/"}})))) 226 | 227 | (deftest datatype-full-iri-capture 228 | (testing "When using a compact IRI to define a default datatype, it should also work for data defined with a full IRI." 229 | (is (= (context/parse {"ex" "https://example.com/" 230 | "xsd" "http://www.w3.org/2001/XMLSchema#" 231 | "ex:rating" {"@type" "xsd:float"}}) 232 | {:type-key "@type" 233 | "ex" {:id "https://example.com/"} 234 | "xsd" {:id "http://www.w3.org/2001/XMLSchema#"} 235 | "ex:rating" {:id "https://example.com/rating" 236 | :type "http://www.w3.org/2001/XMLSchema#float"} 237 | "https://example.com/rating" 238 | {:id "https://example.com/rating" 239 | :type "http://www.w3.org/2001/XMLSchema#float"}})))) 240 | 241 | #?(:clj 242 | (deftest cyclic-context 243 | (testing "compact iri uses itself as a term definition" 244 | (let [result (try (context/parse {"foo" "foo"}) 245 | (catch Exception e e))] 246 | (is (= {:status 400, 247 | :error :json-ld/invalid-iri-mapping, 248 | :context {"foo" "foo"}} 249 | (ex-data result))) 250 | (is (= "A local context contains a term that has an invalid or missing IRI mapping" 251 | (ex-message result))))))) 252 | -------------------------------------------------------------------------------- /test/fluree/json_ld/impl/iri_test.cljc: -------------------------------------------------------------------------------- 1 | (ns fluree.json-ld.impl.iri-test 2 | (:require #?(:clj [clojure.test :as t :refer [deftest testing is]] 3 | :cljs [cljs.test :as t :refer [deftest testing is] :include-macros true]) 4 | [fluree.json-ld.impl.iri :as iri])) 5 | 6 | (deftest prefix-parsing 7 | (testing "Prefix parsing returns prefix and suffix correctly" 8 | 9 | (is (= ["schema" "name"] 10 | (iri/parse-prefix "schema:name"))) 11 | 12 | (is (= ["fluree" "some/namespace"] 13 | (iri/parse-prefix "fluree:some/namespace"))) 14 | 15 | (is (= ["ex" "a"] 16 | (iri/parse-prefix "ex:a"))) 17 | 18 | (is (= ["a" "b"] 19 | (iri/parse-prefix "a:b"))) 20 | 21 | (is (= [":" "schema:name"] 22 | (iri/parse-prefix ":schema:name"))) 23 | 24 | (is (= [":" "schema"] 25 | (iri/parse-prefix ":schema"))) 26 | 27 | (is (nil? (iri/parse-prefix "fluree/some:namespace"))) 28 | 29 | (is (nil? (iri/parse-prefix "fluree/cool"))) 30 | 31 | (is (nil? (iri/parse-prefix "schema::name"))) 32 | 33 | (is (nil? (iri/parse-prefix "schema:"))) 34 | 35 | (is (nil? (iri/parse-prefix "schema:/name"))) 36 | 37 | (is (nil? (iri/parse-prefix "schema:name:"))) 38 | 39 | (is (nil? (iri/parse-prefix "https://schema.org"))) 40 | 41 | (is (nil? (iri/parse-prefix "https://schema.org:bad"))) 42 | 43 | (is (nil? (iri/parse-prefix "schema-name"))))) 44 | -------------------------------------------------------------------------------- /test/fluree/json_ld/impl/normalize_test.cljc: -------------------------------------------------------------------------------- 1 | (ns fluree.json-ld.impl.normalize-test 2 | (:require [clojure.test :refer [deftest is testing]] 3 | [fluree.json-ld.impl.normalize :as normalize] 4 | [clojure.string :as str])) 5 | 6 | ;; basic normalization per JSON Canonicalization Scheme https://datatracker.ietf.org/doc/html/rfc8785 7 | ;; following tests come from examples at https://cyberphone.github.io/doc/security/browser-json-canonicalization.html 8 | 9 | (deftest data-as-map 10 | (testing "Map with some non-standard characters" 11 | (let [data {"peach" "This sorting order", 12 | "péché" "is wrong according to French", 13 | "pêche" "but canonicalization MUST", 14 | "sin" "ignore locale"}] 15 | (is (= "{\"peach\":\"This sorting order\",\"péché\":\"is wrong according to French\",\"pêche\":\"but canonicalization MUST\",\"sin\":\"ignore locale\"}" 16 | (normalize/normalize data {:algorithm :basic 17 | :format :application/json}))))) 18 | 19 | (testing "Map with line break as string and decimal to integer" 20 | (let [data {"1" {"f" {"f" "hi", "F" 5}, "\n" 56.0}, ;; note 56.0 should become "56" 21 | "10" {}, 22 | "" "empty", 23 | "a" {}, 24 | "111" [{"e" "yes", "E" "no"}], 25 | "A" {}}] 26 | (is (= "{\"\":\"empty\",\"1\":{\"\n\":56,\"f\":{\"F\":5,\"f\":\"hi\"}},\"10\":{},\"111\":[{\"E\":\"no\",\"e\":\"yes\"}],\"A\":{},\"a\":{}}" 27 | (normalize/normalize data {:algorithm :basic 28 | :format :application/json}))))) 29 | 30 | (testing "Unicode in string" 31 | (let [data {"Unnormalized Unicode" "A\u030a"}] 32 | (is (= "{\"Unnormalized Unicode\":\"Å\"}" 33 | (normalize/normalize data {:algorithm :basic 34 | :format :application/json}))))) 35 | 36 | (testing "Numbers in different formats and literals" 37 | (let [data {"numbers" [333333333.33333329, 1E30, 4.50, 2e-3, 0.000000000000000000000000001], 38 | "literals" [nil, true, false]}] 39 | (is (= "{\"literals\":[null,true,false],\"numbers\":[333333333.3333333,1e+30,4.5,0.002,1e-27]}" 40 | (normalize/normalize data {:algorithm :basic 41 | :format :application/json}))))) 42 | (testing "Symbol keys" 43 | (let [data {"id" '?s '?p '?o}] 44 | (is (= "{\"?p\":?o,\"id\":?s}" 45 | (normalize/normalize data {:algorithm :basic 46 | :format :application/json}))))) 47 | 48 | ;; Note below fails but should not. Most unicode control set characters (< \u000f) should remain as is 49 | ;; but with lower case hex. Below, \u000F gets parsed but should instead output \u000f 50 | ;; see https://datatracker.ietf.org/doc/html/rfc8785#section-3.2.2.2 bullet #2 51 | ;; Need to figure out a way to efficiently detect and parse this, including in JS 52 | #_(testing "Unicode control set characters remain (but with lowercase hex), numbers, literals" 53 | (let [data {"numbers" [333333333.33333329, 1E30, 4.50, 2e-3, 0.000000000000000000000000001], 54 | "string" "\u20ac$\u000F\u000aA'\u0042\u0022\u005c\\\"/", 55 | "literals" [nil, true, false]}] 56 | (is (= "{\"literals\":[null,true,false],\"numbers\":[333333333.3333333,1e+30,4.5,0.002,1e-27],\"string\":\"€$\\u000f\\nA'B\\\"\\\\\\\\\\\"/\"}" 57 | (normalize data {:algorithm :basic})))))) 58 | 59 | 60 | (deftest data-as-sequence 61 | (testing "Sequence that includes a map" 62 | (let [data [56 {"d" true 63 | "10" nil 64 | "1" []}]] 65 | (is (= "[56,{\"1\":[],\"10\":null,\"d\":true}]" 66 | (normalize/normalize data {:algorithm :basic 67 | :format :application/json})))))) 68 | 69 | (def utf8-bytes [0x7b 0x22 0x70 0x65 0x61 0x63 0x68 0x22 0x3a 70 | 0x22 0x54 0x68 0x69 0x73 0x20 0x73 0x6f 0x72 71 | 0x74 0x69 0x6e 0x67 0x20 0x6f 0x72 0x64 0x65 72 | 0x72 0x22 0x2c 0x22 0x70 0xc3 0xa9 0x63 0x68 73 | 0xc3 0xa9 0x22 0x3a 0x22 0x69 0x73 0x20 0x77 74 | 0x72 0x6f 0x6e 0x67 0x20 0x61 0x63 0x63 0x6f 75 | 0x72 0x64 0x69 0x6e 0x67 0x20 0x74 0x6f 0x20 76 | 0x46 0x72 0x65 0x6e 0x63 0x68 0x22 0x2c 0x22 77 | 0x70 0xc3 0xaa 0x63 0x68 0x65 0x22 0x3a 0x22 78 | 0x62 0x75 0x74 0x20 0x63 0x61 0x6e 0x6f 0x6e 79 | 0x69 0x63 0x61 0x6c 0x69 0x7a 0x61 0x74 0x69 80 | 0x6f 0x6e 0x20 0x4d 0x55 0x53 0x54 0x22 0x2c 81 | 0x22 0x73 0x69 0x6e 0x22 0x3a 0x22 0x69 0x67 82 | 0x6e 0x6f 0x72 0x65 0x20 0x6c 0x6f 0x63 0x61 83 | 0x6c 0x65 0x22 0x7d]) 84 | 85 | (deftest roundtrip 86 | (testing "Using original UTF-8 bytes to construct json, parse, normalize, back to UTF-8" 87 | ;; {"peach":"This sorting order","péché":"is wrong according to French","pêche":"but canonicalization MUST","sin":"ignore locale"} 88 | (let [utf-8 #?(:clj (byte-array utf8-bytes) 89 | :cljs (js/Uint8Array. utf8-bytes)) 90 | to-str #?(:clj (String. utf-8 "UTF-8") 91 | :cljs (reduce str (map js/String.fromCharCode utf-8))) 92 | ;; poor man's json parser - avoiding extra dependency, only works for simple map 93 | parsed (-> to-str 94 | (subs 1 (dec (count to-str))) ;; remove leading/ending '{}' 95 | (str/replace #"\"" "") 96 | (str/split #",") 97 | (->> (mapv #(str/split % #":")) 98 | (into {}))) 99 | normalized (normalize/normalize parsed {:algorithm :basic 100 | :format :application/json}) 101 | utf-8* #?(:clj (.getBytes ^String normalized "UTF-8") 102 | :cljs (map #(.charCodeAt %) normalized))] 103 | (is (= (vec utf-8) 104 | (vec utf-8*)))))) 105 | 106 | ;; Following also fails and needs to get addressed 107 | #_(deftest weird-json 108 | (testing "weird.json example at " 109 | ;; {"\n":"Newline","\r":"Carriage Return","1":"One","":"Browser Challenge","□":"Control","ö":"Latin Small Letter O With Diaeresis","€":"Euro Sign","😂":"Smiley","דּ":"Hebrew Letter Dalet With Dagesh"} 110 | (let [data {"\u20ac" "Euro Sign", 111 | "\r" "Carriage Return", 112 | "\u000a" "Newline", 113 | "1" "One", 114 | "\u0080" "Control\u007f", 115 | "\ud83d\ude02" "Smiley", 116 | "\u00f6" "Latin Small Letter O With Diaeresis", 117 | "\ufb33" "Hebrew Letter Dalet With Dagesh", 118 | "" "Browser Challenge"} 119 | utf-8 (byte-array [0x7b 0x22 0x5c 0x6e 0x22 0x3a 0x22 0x4e 0x65 120 | 0x77 0x6c 0x69 0x6e 0x65 0x22 0x2c 0x22 0x5c 121 | 0x72 0x22 0x3a 0x22 0x43 0x61 0x72 0x72 0x69 122 | 0x61 0x67 0x65 0x20 0x52 0x65 0x74 0x75 0x72 123 | 0x6e 0x22 0x2c 0x22 0x31 0x22 0x3a 0x22 0x4f 124 | 0x6e 0x65 0x22 0x2c 0x22 0x3c 0x2f 0x73 0x63 125 | 0x72 0x69 0x70 0x74 0x3e 0x22 0x3a 0x22 0x42 126 | 0x72 0x6f 0x77 0x73 0x65 0x72 0x20 0x43 0x68 127 | 0x61 0x6c 0x6c 0x65 0x6e 0x67 0x65 0x22 0x2c 128 | 0x22 0xc2 0x80 0x22 0x3a 0x22 0x43 0x6f 0x6e 129 | 0x74 0x72 0x6f 0x6c 0x7f 0x22 0x2c 0x22 0xc3 130 | 0xb6 0x22 0x3a 0x22 0x4c 0x61 0x74 0x69 0x6e 131 | 0x20 0x53 0x6d 0x61 0x6c 0x6c 0x20 0x4c 0x65 132 | 0x74 0x74 0x65 0x72 0x20 0x4f 0x20 0x57 0x69 133 | 0x74 0x68 0x20 0x44 0x69 0x61 0x65 0x72 0x65 134 | 0x73 0x69 0x73 0x22 0x2c 0x22 0xe2 0x82 0xac 135 | 0x22 0x3a 0x22 0x45 0x75 0x72 0x6f 0x20 0x53 136 | 0x69 0x67 0x6e 0x22 0x2c 0x22 0xf0 0x9f 0x98 137 | 0x82 0x22 0x3a 0x22 0x53 0x6d 0x69 0x6c 0x65 138 | 0x79 0x22 0x2c 0x22 0xef 0xac 0xb3 0x22 0x3a 139 | 0x22 0x48 0x65 0x62 0x72 0x65 0x77 0x20 0x4c 140 | 0x65 0x74 0x74 0x65 0x72 0x20 0x44 0x61 0x6c 141 | 0x65 0x74 0x20 0x57 0x69 0x74 0x68 0x20 0x44 142 | 0x61 0x67 0x65 0x73 0x68 0x22 0x7d]) 143 | to-str (String. utf-8 "UTF-8")] 144 | (is (= to-str 145 | (normalize data {:algorithm :basic}))) 146 | ))) 147 | -------------------------------------------------------------------------------- /test/fluree/json_ld/processor/api_test.clj: -------------------------------------------------------------------------------- 1 | (ns fluree.json-ld.processor.api-test 2 | (:require [fluree.json-ld.processor.api :as jld-processor] 3 | [clojure.test :as t :refer [deftest is testing]] 4 | [clojure.string :as str] 5 | [jsonista.core :as json])) 6 | 7 | (def context {"@version" 1.1, 8 | "address" "fluree:address", 9 | "alias" "fluree:alias", 10 | "cool" {"@id" "fluree:cool" "@type" "xsd:boolean"} 11 | "data" {"@id" "fluree:data", "@type" "@id"}, 12 | "DB" "fluree:DB", 13 | "fluree" "https://ns.flur.ee/ledger#", 14 | "id" "@id", 15 | "t" {"@id" "fluree:t", "@type" "xsd:long"}, 16 | "type" "@type" 17 | "xsd" "http://www.w3.org/2001/XMLSchema#",}) 18 | 19 | (def commit 20 | {"@context" context 21 | "address" "", 22 | "alias" {"@value" "test/db19" "@language" "en"}, 23 | "data" {"id" "fluree:db:sha256:bb3u2hayr4pdwunsa5ijdp7txqrmmku5zlhj7dpozetdcr5g7r5n6", 24 | "type" "DB", 25 | "t" 1, 26 | "cool" true}}) 27 | 28 | (def expanded 29 | [{"https://ns.flur.ee/ledger#address" [{"@value" ""}], 30 | "https://ns.flur.ee/ledger#alias" [{"@value" "test/db19", "@language" "en"}], 31 | "https://ns.flur.ee/ledger#data" 32 | [{"@id" "https://ns.flur.ee/ledger#db:sha256:bb3u2hayr4pdwunsa5ijdp7txqrmmku5zlhj7dpozetdcr5g7r5n6", 33 | "@type" ["https://ns.flur.ee/ledger#DB"], 34 | "https://ns.flur.ee/ledger#t" [{"@value" 1, "@type" "http://www.w3.org/2001/XMLSchema#long"}], 35 | "https://ns.flur.ee/ledger#cool" [{"@value" true, "@type" "http://www.w3.org/2001/XMLSchema#boolean"}]}]}]) 36 | 37 | 38 | 39 | (deftest expansion 40 | (testing "inline context" 41 | (let [result (jld-processor/expand commit)] 42 | (is (= expanded 43 | result)))) 44 | 45 | (testing "static context" 46 | (is (= expanded 47 | (jld-processor/expand (assoc commit "@context" 48 | ["https://ns.flur.ee/ledger/v1" 49 | {"cool" {"@id" "fluree:cool" "@type" "xsd:boolean"}}])))) 50 | 51 | (is (= "Unable to load context: http://failure.foo" 52 | (try (jld-processor/expand (assoc commit "@context" "http://failure.foo")) 53 | (catch Exception e 54 | (:cause (Throwable->map e))))))) 55 | 56 | (testing "remote context" 57 | (let [test-docloader (fn [_ _] (json/write-value-as-string {"@context" {"foo" "http://example.com/foo#"}}))] 58 | (is (= [{"http://example.com/foo#bar" [{"@value" 1}]}] 59 | (jld-processor/expand {"@context" "foo:context" "foo:bar" 1} 60 | {:document-loader test-docloader}))) 61 | (is (= "Unable to load context: foo:context" 62 | (try (jld-processor/expand {"@context" "foo:context" "foo:bar" 1} 63 | {:document-loader (fn [_ _] (throw (ex-info "borken loader" {})))}) 64 | (catch Exception e 65 | (:cause (Throwable->map e)))))))) 66 | 67 | (testing "remote context failure" 68 | (is (= "Unable to load context: http://failure.foo" 69 | (try (jld-processor/expand (assoc commit "@context" "http://failure.foo")) 70 | (catch Exception e 71 | (:cause (Throwable->map e)))))))) 72 | 73 | (deftest compaction 74 | (let [result (jld-processor/compact (jld-processor/expand commit) context)] 75 | (is (= commit result)))) 76 | 77 | (deftest to-rdf 78 | (let [result (sort (str/split-lines (jld-processor/to-rdf commit)))] 79 | (is (= [" ." 80 | " \"true\"^^ ." 81 | " \"1\"^^ ." 82 | "_:b0 \"\" ." 83 | "_:b0 \"test/db19\"@en ." 84 | "_:b0 ."] 85 | result)))) 86 | 87 | #_(deftest from-rdf 88 | (let [result (jld-processor/from-rdf (jld-processor/to-rdf commit))] 89 | (is (= [{"@id" "_:b0", 90 | "https://ns.flur.ee/ledger#address" [{"@value" ""}], 91 | "https://ns.flur.ee/ledger#alias" 92 | [{"@value" "test/db19", "@language" "en"}], 93 | "https://ns.flur.ee/ledger#data" 94 | [{"@id" 95 | "https://ns.flur.ee/ledger#db:sha256:bb3u2hayr4pdwunsa5ijdp7txqrmmku5zlhj7dpozetdcr5g7r5n6"}]} 96 | {"@id" 97 | "https://ns.flur.ee/ledger#db:sha256:bb3u2hayr4pdwunsa5ijdp7txqrmmku5zlhj7dpozetdcr5g7r5n6", 98 | "https://ns.flur.ee/ledger#address" 99 | [{"@value" 100 | "fluree:memory://e2c8cf4429d7fcd6382fe2c890cf4c3fa2d8d0039b1981ff27e1ee2a05848569"}], 101 | "https://ns.flur.ee/ledger#cool" 102 | [{"@value" "true", "@type" "xsd:boolean"}], 103 | "https://ns.flur.ee/ledger#flakes" 104 | [{"@value" "55", "@type" "xsd:long"}], 105 | "https://ns.flur.ee/ledger#size" 106 | [{"@value" "5057", "@type" "xsd:long"}], 107 | "https://ns.flur.ee/ledger#t" 108 | [{"@value" "1", "@type" "xsd:long"}]}] 109 | result)))) 110 | 111 | (deftest canonize 112 | (let [result (jld-processor/canonize commit)] 113 | (is (= " .\n \"true\"^^ .\n \"1\"^^ .\n_:c14n0 \"\" .\n_:c14n0 \"test/db19\"@en .\n_:c14n0 .\n" 114 | result)))) 115 | -------------------------------------------------------------------------------- /test/fluree/json_ld/processor/api_test.cljs: -------------------------------------------------------------------------------- 1 | (ns fluree.json-ld.processor.api-test 2 | (:require [fluree.json-ld.processor.api :as jld-processor] 3 | [cljs.test :as t :refer [is deftest testing async] :include-macros true])) 4 | 5 | (def context {"@version" 1.1, 6 | "address" "fluree:address", 7 | "alias" "fluree:alias", 8 | "cool" {"@id" "fluree:cool" "@type" "xsd:boolean"} 9 | "data" {"@id" "fluree:data", "@type" "@id"}, 10 | "DB" "fluree:DB", 11 | "fluree" "https://ns.flur.ee/ledger#", 12 | "id" "@id", 13 | "t" {"@id" "fluree:t", "@type" "xsd:long"}, 14 | "type" "@type" 15 | "xsd" "http://www.w3.org/2001/XMLSchema#",}) 16 | 17 | (def commit 18 | {"@context" context 19 | "address" "", 20 | "alias" {"@value" "test/db19" "@language" "en"}, 21 | "data" {"id" "fluree:db:sha256:bb3u2hayr4pdwunsa5ijdp7txqrmmku5zlhj7dpozetdcr5g7r5n6", 22 | "type" "DB", 23 | "t" 1, 24 | "cool" true}}) 25 | 26 | (def expanded 27 | [{"https://ns.flur.ee/ledger#address" [{"@value" ""}], 28 | "https://ns.flur.ee/ledger#alias" [{"@value" "test/db19", "@language" "en"}], 29 | "https://ns.flur.ee/ledger#data" 30 | [{"@id" "https://ns.flur.ee/ledger#db:sha256:bb3u2hayr4pdwunsa5ijdp7txqrmmku5zlhj7dpozetdcr5g7r5n6", 31 | "@type" ["https://ns.flur.ee/ledger#DB"], 32 | "https://ns.flur.ee/ledger#t" [{"@value" 1, "@type" "http://www.w3.org/2001/XMLSchema#long"}], 33 | "https://ns.flur.ee/ledger#cool" [{"@value" true, "@type" "http://www.w3.org/2001/XMLSchema#boolean"}]}]}]) 34 | 35 | (deftest expansion--inline-context 36 | (async done 37 | (-> (jld-processor/expand commit) 38 | (.then (fn [result] 39 | (is (= expanded 40 | result)) 41 | (done)))))) 42 | 43 | (deftest expansion--static-context 44 | (async done 45 | (-> (jld-processor/expand (assoc commit "@context" 46 | ["https://ns.flur.ee/ledger/v1" 47 | {"cool" {"@id" "fluree:cool" "@type" "xsd:boolean"}}])) 48 | (.then (fn [result] 49 | (is (= expanded 50 | result)) 51 | (done)))))) 52 | (deftest expansion--static-context-failure 53 | (async done 54 | (-> (jld-processor/expand (assoc commit "@context" "http://failure.foo")) 55 | (.catch (fn [error] 56 | (is (not (nil? error))) 57 | (done)))))) 58 | 59 | (deftest expansion--remote-context 60 | (async done 61 | (-> (jld-processor/expand {"@context" "foo:context" "foo:bar" 1} 62 | {:document-loader (fn [_ _] 63 | (->> {"@context" {"foo" "http://example.com/foo#"}} 64 | (clj->js) 65 | (.stringify js/JSON)))}) 66 | (.then (fn [result] 67 | (is (= [{"http://example.com/foo#bar" [{"@value" 1}]}] 68 | result)) 69 | (done)))))) 70 | 71 | (deftest expansion--remote-context-failure 72 | (async done 73 | (-> (jld-processor/expand {"@context" "foo:context" "foo:bar" 1} 74 | {:document-loader (fn [_ _] (throw (ex-info "Broken loader" {})))}) 75 | (.catch (fn [error] 76 | (is (not (nil? error))) 77 | (done)))))) 78 | 79 | (deftest compaction 80 | (async done 81 | (-> (jld-processor/expand commit) 82 | (.then #(jld-processor/compact % context)) 83 | (.then (fn [result] 84 | (is (= commit result)) 85 | (done)))))) 86 | 87 | (deftest to-rdf 88 | (async done 89 | (-> (jld-processor/to-rdf commit) 90 | (.then (fn [result] 91 | (is (= " .\n \"true\"^^ .\n \"1\"^^ .\n_:b0 \"\" .\n_:b0 \"test/db19\"@en .\n_:b0 .\n" 92 | result)) 93 | (done)))))) 94 | 95 | (deftest to-rdf--remote-context 96 | (async done 97 | (-> (jld-processor/to-rdf {"@context" "https://ns.flur.ee/ledger/v1" 98 | "address" ""}) 99 | (.then (fn [result] 100 | (is (= "_:b0 \"\" .\n" 101 | result)) 102 | (done)))))) 103 | 104 | (deftest from-rdf 105 | (async done 106 | (-> (jld-processor/to-rdf commit) 107 | (.then #(jld-processor/from-rdf %)) 108 | (.then (fn [result] 109 | (is (= [{"@id" "_:b0", 110 | "https://ns.flur.ee/ledger#address" [{"@value" ""}], 111 | "https://ns.flur.ee/ledger#alias" 112 | [{"@value" "test/db19", "@language" "en"}], 113 | "https://ns.flur.ee/ledger#data" 114 | [{"@id" 115 | "https://ns.flur.ee/ledger#db:sha256:bb3u2hayr4pdwunsa5ijdp7txqrmmku5zlhj7dpozetdcr5g7r5n6"}]} 116 | {"@id" 117 | "https://ns.flur.ee/ledger#db:sha256:bb3u2hayr4pdwunsa5ijdp7txqrmmku5zlhj7dpozetdcr5g7r5n6", 118 | "@type" ["https://ns.flur.ee/ledger#DB"], 119 | "https://ns.flur.ee/ledger#cool" 120 | [{"@value" "true", 121 | "@type" "http://www.w3.org/2001/XMLSchema#boolean"}], 122 | "https://ns.flur.ee/ledger#t" 123 | [{"@value" "1", 124 | "@type" "http://www.w3.org/2001/XMLSchema#long"}]}] 125 | result)) 126 | (done)))))) 127 | 128 | (deftest canonize 129 | (async done 130 | (-> (jld-processor/canonize commit) 131 | (.then (fn [result] 132 | (is (= " .\n \"true\"^^ .\n \"1\"^^ .\n_:c14n0 \"\" .\n_:c14n0 \"test/db19\"@en .\n_:c14n0 .\n" 133 | result)) 134 | (done)))))) 135 | 136 | (deftest canonize--remote-context 137 | (async done 138 | (-> (jld-processor/canonize {"@context" "https://ns.flur.ee/ledger/v1" 139 | "address" ""}) 140 | (.then (fn [result] 141 | (is (= "_:c14n0 \"\" .\n" 142 | result)) 143 | (done)))))) 144 | 145 | (comment 146 | (t/run-tests) 147 | 148 | 149 | 150 | ) 151 | --------------------------------------------------------------------------------