{"id":18087879,"url":"https://github.com/ramp-shapes/ramp-shapes","last_synced_at":"2025-06-30T10:33:35.983Z","repository":{"id":47986699,"uuid":"175675083","full_name":"ramp-shapes/ramp-shapes","owner":"ramp-shapes","description":"RAMP shapes: declarative RDF ↔ algebraic data type mapping","archived":false,"fork":false,"pushed_at":"2025-05-07T06:45:22.000Z","size":325,"stargazers_count":7,"open_issues_count":0,"forks_count":0,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-05-14T17:18:26.493Z","etag":null,"topics":["adt","json","language","mapping","metadata","rdf"],"latest_commit_sha":null,"homepage":"https://ramp-shapes.github.io/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ramp-shapes.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-03-14T18:08:53.000Z","updated_at":"2021-10-21T10:29:28.000Z","dependencies_parsed_at":"2024-01-17T00:10:25.855Z","dependency_job_id":"d32aa0af-cb7e-4c43-8ea1-2f15b230477c","html_url":"https://github.com/ramp-shapes/ramp-shapes","commit_stats":null,"previous_names":["ram-shapes/ram-shapes"],"tags_count":10,"template":false,"template_full_name":null,"purl":"pkg:github/ramp-shapes/ramp-shapes","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ramp-shapes%2Framp-shapes","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ramp-shapes%2Framp-shapes/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ramp-shapes%2Framp-shapes/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ramp-shapes%2Framp-shapes/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ramp-shapes","download_url":"https://codeload.github.com/ramp-shapes/ramp-shapes/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ramp-shapes%2Framp-shapes/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":260176243,"owners_count":22970138,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["adt","json","language","mapping","metadata","rdf"],"created_at":"2024-10-31T17:09:16.142Z","updated_at":"2025-06-30T10:33:35.912Z","avatar_url":"https://github.com/ramp-shapes.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# RAMP shapes: declarative RDF ↔ algebraic data type mapping [![npm version](https://badge.fury.io/js/ramp-shapes.svg)](https://badge.fury.io/js/ramp-shapes)\n\n[Home page](https://ramp-shapes.github.io/) | [Introductory paper](https://www.researchgate.net/publication/337724413_RAMP_Shapes_Declarative_RDF_ADT_Mapping) | [Specification draft](https://ramp-shapes.github.io/ramp-shapes-spec/) | [Playground](https://ramp-shapes.github.io/playground.html)\n\n**RAMP** is a type construction language, specification and an implementation of mapping operations between RDF graphs and structured data types.\n\n## Features\n**RAMP** introduces a language based on RDF which allows to describe a runtime object interface with so-called \"shapes\". The shapes are basically types augumented with metadata to map them into RDF graph. Usage of such shapes allows to:\n\n * Map RDF graph data into JS objects.\n * Generate RDF quad/triple data from JS objects.\n * Construct SPARQL queries to fetch necessary data for given shapes.\n * *(In the future)* Validate that runtime object structure matches specified shape.\n\n### Feature comparison with other RDF modelling languages\n\n| Feature | [OWL/RDFS](https://www.w3.org/TR/owl2-overview/) | [SHACL](https://www.w3.org/TR/shacl/) | [ShEx](https://shex.io/shex-semantics/index.html) | [JSON-LD](https://www.w3.org/TR/json-ld11/) | [**RAMP Shapes**](https://ramp-shapes.github.io/) |\n|---|---|---|---|---|---|\n| Describes closed RDF graph structure | ❌ | ✅ | ✅ | ✅ | ✅ |\n| Describes data mapping / serialization | ❌ | ❌ | ❌ | requires frame definition | ✅ |\n| Has ability to generate query and deserialize results based on shapes | ❌ | ❌ | ❌ | ❌ | ✅ |\n| Has RDF representation | ✅ | ✅ | ✅ | ❌ | ✅ |\n| Supports RDF lists | ❌ | [with workaround](https://www.topquadrant.com/constraints-on-rdflists-using-shacl/) | ❌ | ✅ | ✅ |\n| Supports shape unions | ✅ | through shape targets | ✅ | ❌ | ✅ |\n| Supports cardinality constraints (min/max) | ✅ | ✅ | ✅ | ❌ | ✅ |\n| Supports recursive shapes | ✅ | depends on implementation | ✅ | ❌ | ✅ |\n| Supports property paths | ❌ | ✅ | ❌ | ❌ | ✅ |\n| Supports ignoring optional non-matching shapes | ❌ | by declaring shape severity | ❌ | ❌ | ✅ |\n\n## Installation\n\nInstall with `npm install --save ramp-shapes`\n\n## Usage\n\nTry out on the interactive [playground](https://ramp-shapes.github.io/playground.html).\n\n```ts\nimport * as Ramp from 'ramp-shapes';\nimport * as N3 from 'n3';\nimport * as SparqlJs from 'sparqljs';\n\n// get graph triples (source data)\nconst dataset = Ramp.Rdf.dataset(new N3.Parser().parse(`\n    @prefix ex: \u003chttp://example.com/schema/\u003e.\n    @prefix : \u003chttp://example.com/data/\u003e.\n\n    :anno1 a ex:Annotation;\n        ex:start :point1;\n        ex:end (\"1\" \"2\").\n\n    :point1 a ex:Point;\n        ex:position 42.\n`));\n\n// define custom shapes using Turtle syntax\nconst shapes = Ramp.frameShapes(Ramp.Rdf.dataset(new N3.Parser().parse(`\n    @prefix rdf: \u003chttp://www.w3.org/1999/02/22-rdf-syntax-ns#\u003e.\n    @prefix rdfs: \u003chttp://www.w3.org/2000/01/rdf-schema#\u003e.\n    @prefix xsd: \u003chttp://www.w3.org/2001/XMLSchema#\u003e.\n    @prefix ramp: \u003chttp://ramp-shapes.github.io/schema#\u003e.\n    @prefix ex: \u003chttp://example.com/schema/\u003e.\n\n    ex:Annotation a ramp:Record;\n        ramp:typeProperty [\n            ramp:name \"type\";\n            ramp:path rdf:type;\n            ramp:shape [ a ramp:Resource; ramp:termValue ex:Annotation ]\n        ];\n        ramp:property [\n            ramp:name \"id\";\n            ramp:path ();\n            ramp:shape [ a ramp:Resource ]\n        ];\n        ramp:property [\n            ramp:name \"start\";\n            ramp:path ex:start;\n            ramp:shape ex:Selector\n        ];\n        ramp:property [\n            ramp:name \"end\";\n            ramp:path ex:end;\n            ramp:shape [ a ramp:Optional; ramp:item ex:Selector ]\n        ].\n\n    ex:Selector a ramp:AnyOf;\n        ramp:variant ex:Point, ex:Path.\n\n    ex:Point a ramp:Record;\n        ramp:typeProperty [\n            ramp:name \"type\";\n            ramp:path rdf:type;\n            ramp:shape [ a ramp:Resource; ramp:termValue ex:Point ]\n        ];\n        ramp:property [\n            ramp:name \"position\";\n            ramp:path ex:position;\n            ramp:shape [ a ramp:Literal; ramp:termDatatype xsd:integer ]\n        ].\n\n    ex:Path a ramp:List;\n        ramp:item [ a ramp:Literal; ramp:termDatatype xsd:string ].\n`)));\n\n// choose entry point shape\nconst shape = shapes.find(s =\u003e\n  s.id.value === 'http://example.com/schema#Annotation'\n);\n\n// use defined shapes to lower RDF graph into JS objects...\nconst matches = Ramp.frame({shape, dataset});\nfor (const match of matches) {\n  /* match.value object has ex:Annotation shape, e.g.:\n    {\n      \"type\": \"http://example.com/schema/Annotation\",\n      \"id\": \"http://example.com/data/anno1\",\n      \"start\": {\n        \"type\": \"http://example.com/schema/Point\",\n        \"position\": 42\n      },\n      \"end\": [\"1\", \"2\"]\n    }\n  */\n\n  // ... and lift JS object back into an RDF graph\n  const quads = Ramp.flatten({shape, value: match.value});\n  /* quads is Iterable\u003cRdf.Quad\u003e, e.g.:\n\n    :anno1 a ex:Annotation;\n        ex:start _:record_044916_1.\n    _:record_044916_1 a ex:Point;\n        ex:position \"42\"^^xsd:integer.\n    :anno1 ex:end _:list_044916_2.\n    _:list_044916_2 rdf:first \"1\";\n        rdf:rest _:list_044916_3.\n    _:list_044916_3 rdf:first \"2\";\n        rdf:rest rdf:nil.\n  */\n}\n\n// another application of defined shapes is to generate a CONSTRUCT query\n// to get necessary graph data for framing\nconst query = Ramp.generateQuery({\n  shape,\n  // (optionally) specify prefixes for SPARQL\n  prefixes: {\n    rdf: \"http://www.w3.org/1999/02/22-rdf-syntax-ns#\",\n    rdfs: \"http://www.w3.org/2000/01/rdf-schema#\",\n    xsd: \"http://www.w3.org/2001/XMLSchema#\",\n    ex: \"http://example.com/schema/\",\n    \"\": \"http://example.com/data/\",\n  }\n});\nconst queryString = new SparqlJs.Generator().stringify(query);\n/* query is a CONSTRUCT query in SPARQL.js runtime format:\n\n  PREFIX rdf: \u003chttp://www.w3.org/1999/02/22-rdf-syntax-ns#\u003e\n  PREFIX ex: \u003chttp://example.com/schema/\u003e\n  CONSTRUCT {\n    ?record_1 rdf:type ex:Annotation.\n    ?record_1 ex:start ?record_4.\n    ?record_4 rdf:type ex:Point.\n    ?record_4 ex:position ?literal_5.\n    ?record_1 ex:start ?list_6.\n    ?listNode_7 rdf:rest ?nextNode_8.\n    ?listNode_7 rdf:first ?literal_9.\n    ?record_1 ex:end ?record_11.\n    ?record_11 rdf:type ex:Point.\n    ?record_11 ex:position ?literal_12.\n    ?record_1 ex:end ?list_13.\n    ?listNode_14 rdf:rest ?nextNode_15.\n    ?listNode_14 rdf:first ?literal_16.\n  }\n  WHERE {\n    ?record_1 rdf:type ex:Annotation.\n    {\n      ?record_1 ex:start ?record_4.\n      ?record_4 rdf:type ex:Point.\n      ?record_4 ex:position ?literal_5.\n    }\n    UNION\n    {\n      ?record_1 ex:start ?list_6.\n      ?list_6 (rdf:rest*) ?listNode_7.\n      ?listNode_7 rdf:rest ?nextNode_8.\n      ?listNode_7 rdf:first ?literal_9.\n    }\n    OPTIONAL {\n      {\n        ?record_1 ex:end ?record_11.\n        ?record_11 rdf:type ex:Point.\n        ?record_11 ex:position ?literal_12.\n      }\n      UNION\n      {\n        ?record_1 ex:end ?list_13.\n        ?list_13 (rdf:rest*) ?listNode_14.\n        ?listNode_14 rdf:rest ?nextNode_15.\n        ?listNode_14 rdf:first ?literal_16.\n      }\n    }\n  }\n */\n```\n\n## References\n\nMorozov A., Wohlgenannt G., Mouromtsev D., Pavlov D., Emelyanov Y. (2019) RAMP Shapes: Declarative RDF ↔ ADT Mapping. In: Garoufallou E., Fallucchi F., William De Luca E. (eds) Metadata and Semantic Research. MTSR 2019. Communications in Computer and Information Science, vol 1057. Springer, Cham\n\nhttps://link.springer.com/chapter/10.1007/978-3-030-36599-8_4\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Framp-shapes%2Framp-shapes","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Framp-shapes%2Framp-shapes","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Framp-shapes%2Framp-shapes/lists"}