{"id":13930238,"url":"https://github.com/KNowledgeOnWebScale/walder","last_synced_at":"2025-07-19T12:32:06.102Z","repository":{"id":39626671,"uuid":"288399454","full_name":"KNowledgeOnWebScale/walder","owner":"KNowledgeOnWebScale","description":"Walder offers an easy way to set up a website or Web API on top of decentralized knowledge graphs.","archived":false,"fork":false,"pushed_at":"2024-04-29T12:43:56.000Z","size":29997,"stargazers_count":62,"open_issues_count":29,"forks_count":8,"subscribers_count":7,"default_branch":"development","last_synced_at":"2024-08-08T18:26:51.836Z","etag":null,"topics":["knowledge-graph","linked-data","rdf","solid","web-api","website"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","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/KNowledgeOnWebScale.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2020-08-18T08:30:46.000Z","updated_at":"2024-07-06T18:06:37.000Z","dependencies_parsed_at":"2023-11-28T11:45:52.348Z","dependency_job_id":null,"html_url":"https://github.com/KNowledgeOnWebScale/walder","commit_stats":{"total_commits":397,"total_committers":10,"mean_commits":39.7,"dds":0.4534005037783375,"last_synced_commit":"77f9a45f5ebfb0f17cbc8a1f3f51a4a7c9da9a7f"},"previous_names":[],"tags_count":15,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KNowledgeOnWebScale%2Fwalder","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KNowledgeOnWebScale%2Fwalder/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KNowledgeOnWebScale%2Fwalder/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KNowledgeOnWebScale%2Fwalder/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/KNowledgeOnWebScale","download_url":"https://codeload.github.com/KNowledgeOnWebScale/walder/tar.gz/refs/heads/development","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":226607620,"owners_count":17658484,"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":["knowledge-graph","linked-data","rdf","solid","web-api","website"],"created_at":"2024-08-07T18:05:23.801Z","updated_at":"2024-11-26T19:30:58.051Z","avatar_url":"https://github.com/KNowledgeOnWebScale.png","language":"JavaScript","readme":"![logo of Walder](logo/logo.png)\n\nWalder offers an easy way to set up a website or Web API on top of decentralized knowledge graphs.\nKnowledge graphs incorporate data together with the meaning of that data.\nThis makes it possible to combine data from multiple knowledge graphs,\neven if different, independent parties maintain or host them.\nKnowledge graphs can be hosted via \n[Solid](https://solidproject.org/) PODs, \n[SPARQL](https://www.w3.org/TR/sparql11-query/) endpoints, \n[Triple Pattern Fragments](https://linkeddatafragments.org/) interfaces, \n[RDF](https://www.w3.org/TR/rdf11-concepts/) files, \nand so on.\nUsing content negotiation, \nWalder makes the data in these knowledge graphs available to clients \nvia HTML, RDF, and JSON-LD.\nUsers define in a configuration file which data Walder uses and \nhow it processes this data.\nFind out which APIs are built with Walder [here](#built-with-walder).\n\n**Table of contents**\n\n- [Installation](#installation)\n- [Usage](#usage)\n  - [CLI](#cli)\n  - [Library](#library)\n  - [Config file structure](#config-file-structure)\n    - [Resources](#resources)\n    - [Path entry](#path-entry)\n  - [Example](#example)\n  - [Options for GraphQL-LD queries](#options-for-graphql-ld-queries)\n  - [Multiple config files](#multiple-config-files)\n  - [Content negotiation](#content-negotiation)\n    - [RDF](#rdf)\n  - [HTML templates](#html-templates)\n    - [Accessing query results in view templates](#accessing-query-results-in-view-templates)\n    - [Using layouts in view templates](#using-layouts-in-view-templates)\n    - [Accessing front-matter metadata in view templates and layout templates](#accessing-front-matter-metadata-in-view-templates-and-layout-templates)\n- [Input validation](#input-validation)\n- [Error handling](#error-handling)\n  - [Errors](#errors)\n    - [Global](#global)\n    - [Pipe modules](#pipe-modules)\n    - [GraphQL-LD](#graphql-ld)\n  - [Example](#example-1)\n- [Developing your website](#developing-your-website)\n- [Dependencies](#dependencies)\n- [Tests](#tests)\n- [Built with Walder](#built-with-walder)\n- [License](#license)\n\n## Installation\n\nInstall Walder globally via `yarn global add walder`.\n\nFor development, follow these steps:\n\n1. Clone the repository.\n2. Install dependencies via `yarn install`.\n3. Install Walder globally via `$ yarn global add file:$(pwd)`.\n\n## Usage\n\nWalder is available as a [CLI](#cli) and JavaScript [library](#library).\n\n### CLI\n\n```bash\nUsage: walder [options]\n\nOptions:\n  -v, --version              output the version number\n  -c, --config \u003cconfigFile\u003e  YAML configuration file input\n  -p, --port [portNumber]    server port number (default: 3000)\n  -l, --log [level]          enable logging and set logging level (one of [error, warn, info, verbose, debug]) (default: \"info\")\n  --no-cache                 disable Comunica default caching\n  --lenient                  turn Comunica errors on invalid data into warnings\n  -h, --help                 output usage information\n```\n\n### Library\n\n```js\n// From the root directory\nconst Walder = require('.');\n\nconst configFilePath = 'path/to/configfile';\nconst port = 9000; // Defaults to 3000 \nconst logging = 'info'; // Defaults to 'info' \nconst cache = false;  // Defaults to true\nconst lenient = true; // Defaults to false \n\nconst walder = new Walder(configFilePath, {port, logging, cache, lenient, cwd});\n\nwalder.activate();    // Starts the server\nwalder.deactivate();  // Stops the server\n```\n\n### Config file structure\n\nYou write a config file in YAML following the [OpenAPI 3.0 specification](https://swagger.io/docs/specification/basic-structure/).\nThe config file must have the following structure:\n\n```yaml\nopenapi: 3.0.2\ninfo:  # OpenAPI metadata\n  title: 'Example site'\n  version: 0.1.0\nx-walder-resources:  # Directories used by Walder - OPTIONAL\n  root:  # Path to the root folder of the directories used by Walder (absolute or relative to the directory containing the config file) - OPTIONAL (default: .)\n  views:  # Path to directory containing view template files (absolute or relative to the root folder) - OPTIONAL (default: views)\n  pipe-modules:  # Path to directory containing local pipe modules (absolute or relative to the root folder) - OPTIONAL (default: pipe-modules)\n  public:  # Path to directory containing all files that should be available statically (e.g. stylesheets) (absolute or relative to the root folder) - OPTIONAL (default: public)\n  layouts: # Path to directory containing all layout template files that can be used by view template files (absolute or relative to the root folder) - OPTIONAL (default: layouts)\nx-walder-datasources:  # Default list of data sources\n  - ...  # E.g. link to SPARQL endpoint or a GraphQL-LD query\npaths:  # List of path entries\n  path-entry-1:\n    ...\n  path-entry-2:\n    ...\nx-walder-errors: # Default error page views - status codes with files containing the HTML view template (absolute path or relative to the views directory)\n  404: ...\n  500: ...\n  ...\n```\n\n#### Resources\n\nThe `x-walder-resources` key of the config file contains paths to directories used by Walder.\nThis key and it's values are optional. \nIf a user does not give paths, \nWalder uses the following default values relative to the directory of the config file.\n\n```yaml\nroot: .\nviews: views\npipe-modules: pipe-modules\npublic: public\nlayouts: layouts\n```\n\nTo prevent Walder from making the wrong files public, \nwhen a user does not give a path to the `public` field, \nWalder creates a new directory `public` if it does not find this directory in the current working directory and uses that one.\n\n#### Path entry\n\nA path entry defines a route and has the following structure:\n\n```yaml\npath:  # The path linked to this query\n  request:  # The HTTP request type (GET, POST, etc.)\n    summary: ...  # Short description\n     parameters:  # Path variables/Query parameters\n        - in: ...  # 'path' or 'query'\n          name: ...  # Name of the parameter\n          schema:\n            type: ... # Type of the parameter\n          description: ...  # Description of the parameter\n    x-walder-query:\n      graphql-query: ...  # One or more GraphQL queries\n      json-ld-context: ...  # The JSON-LD corresponding to the GraphQL query\n      sparql-query: ... # One or more SPARQL queries\n      json-ld-frame: ... # A JSON-LD frame that should be applied to the result of a SPARQL query \n      options: # Global options that will be applied to all the graphql-queries of this path (OPTIONAL)\n      datasources:  # Query specific datasources (OPTIONAL)\n        additional: ...  # Boolean stating that the following datasources are meant to be used on top of the default ones\n        sources:  # List of query specific datasources\n          - ...  # E.g. link to SPARQL endpoint\n    x-walder-postprocessing:  # The (list of) pipe modules used for postprocessing\n      module-id:  # Identifier of the pipe module\n        source: ...  # Path leading to source code of the pipe module (absolute path or relative to the pipe-modules directory)\n        parameters: # the parameters for the pipe module (OPTIONAL)\n          - _data # (DEFAULT) this gives all the data, but all paths in the data object are supported (e.g. _data.0.employee)\n          - ... # Additional parameters if your function supports those (OPTIONAL)\n    responses:  # Status codes with files containing the HTML view template (absolute path or relative to the views directory)\n      200: ...  # (REQUIRED)\n      500: ...  # (OPTIONAL)\n```\n\n### Example\n\nThe following command starts a server on port 3000 (default) using an example config file.\n\n`$ walder -c example/config.yaml `\n\nThis will start a server on `localhost:3000` with the following routes:\n\n* \u003chttp://localhost:3000/bradpitt-directors\u003e - Returns a list of directors of movies starring Brad Pitt.\n* \u003chttp://localhost:3000/music/{musician}\u003e - Returns a list of songs by a given musician.\nFor example, \u003chttp://localhost:3000/music/Lady%20Gaga\u003e returns a list of songs by Lady Gaga.\n* \u003chttp://localhost:3000/artist/{artist}?writer={name}\u003e - Returns a list of a given artist's songs \nselecting those written by a specific person identified by name. \nFor example, \u003chttp://localhost:3000/artist/David%20Bowie?writer=John%20Lennon\u003e returns a list of \na given artist's songs written by a specific person.\n* \u003chttp://localhost:3000/music/{artist}/postprocessed\u003e - Returns a list of songs by a given artist \nthat have 'star' in the title, using pipe modules.\nFor example, \u003chttp://localhost:3000/music/David%20Bowie/postprocessed\u003e returns a list of songs by David Bowie that \nhave 'star' in the title.\n\n### Options for GraphQL-LD queries\n\nIn the path entry above, \nthe user defined `options` as a global (optional) identifier that Walder uses for every query of that path.\nWe have two options where we can choose from: \n`sort` and `remove-duplicates`. \nWith given syntax:\n\n```yaml\noptions:\n  sort: # Enable sorting on the data (OPTIONAL)\n    object: # JSONPath to the object you want to sort for\n    selectors: # The values inside the object over which you want to sort\n      - ... # The default option when you want ascending order, just give the value (JSONPath notation supported for further nesting)\n      - value: ...  # When you want descending order, specify the value/order (JSONPath notation supported for further nesting)\n        order: desc\n  remove-duplicates: # Enable the removal of duplicates of the data (OPTIONAL)\n    object: ... # The JSONPath tot the object that you want to compare\n    value: ... # The value that has to be compared to determine whether it's duplicate (JSONPath notation is also supported for further nesting)\n```\n\nIf you do not want `options` to be global for the whole path, \nyou can define `options` per query.\n\n```yaml\npath:  # The path linked to this query\n  request:  # The HTTP request type (GET, POST, etc.)\n    summary: ...  # Short description\n     parameters:  # Path variables/Query parameters\n        - in: ...  # 'path' or 'query'\n          name: ...  # Name of the parameter\n          schema:\n            type: ... # Type of the parameter\n          description: ...  # Description of the parameter\n    x-walder-query:\n      graphql-query: ...  # One or more GraphQL queries\n        name:\n          query: ... # The GraphQL query\n          options: # options that will be applied only to this specific graphql-query (OPTIONAL)\n...\n```\n\nThe following command starts a server using [this](example/config-sorting-duplicates.yaml) config file.\n\n`$ walder -c example/config-sorting-duplicates.yaml`\n\nThis will start a server on `localhost:3000` with the following routes:\n\n* \u003chttp://localhost:3000/music/{musician}/sorted\u003e - \nReturns a list of songs with their artists written by a given musician. \nWalder sorts the songs in descending order by song name.\nFor example, \u003chttp://localhost:3000/music/Marcella%20Detroit/sorted\u003e returns a list of such songs written by Marcella Detroit.\n* \u003chttp://localhost:3000/music/{musician}/no_duplicates\u003e - \nReturns a list of songs with their artists written by a given musician.\nWalder removes duplicate song names from the list.\nFor example, \u003chttp://localhost:3000/music/Marcella%20Detroit/no_duplicates\u003e returns a list of such songs by John Marcella Detroit.\n* \u003chttp://localhost:3000/movies/{musician}/everything_together\u003e - \nReturns a list of songs with their artists written by a given musician.\nWalder sorts the songs in descending order by song name and removes duplicate song names.\nFor example, \u003chttp://localhost:3000/music/Marcella%20Detroit/everything_together\u003e returns a list of such songs by Marcella Detroit.\n* \u003chttp://localhost:3000/artist/{artist}\u003e - \nReturns a list of song names and movie URLs for a given artist. \nWalder removes duplicate songs based on their names and \nsorts movies in descending order by their URLs.\nFor example, \u003chttp://localhost:3000/artist/David%20Bowie\u003e returns a list of such songs and movies.\n\n### Multiple config files\n\nYou can split a config file in multiple files, \nusing the `$ref` keyword. \nWe follow the [OpenAPI 3.0 spec](https://swagger.io/docs/specification/using-ref/) \nthat explains how to use the referencing.\n\nWhen first referenced you need to use the path beginning from the directory of the config file, \nbut if the referenced file has references itself, \nit can use paths relative to its own location, as shown below.\n\nThe actual config file referencing its paths\n```yaml\nopenapi: 3.0.2\ninfo:\n  title: 'Example site'\n  version: 0.1.0\nx-walder-resources:\n  path: ./\n  views: views\n  pipe-modules: pipeModules\n  public: public\nx-walder-datasources:\n  - http://fragments.dbpedia.org/2016-04/en\npaths:\n  /music/{musician}:\n    $ref: './paths/music_musician.yaml'\n  /movies/{actor}:\n    $ref: './paths/movies_actor.yaml'\nx-walder-errors:\n  404:\n    description: page not found error\n    x-walder-input-text/html: error404.html\n  500:\n    description: internal server error\n    x-walder-input-text/html: error500.html\n```\n\nBelow you see `./example/paths/movies_actor.yaml` with reference with path relative to its own location\n\n```yaml\nget:\n  summary: Returns a list of the all movies the given actor stars in\n  parameters:\n    - in: path\n      name: actor\n      required: true\n      schema:\n        type: string\n      description: The target actor\n  x-walder-query:\n    $ref: '../walderQueryInfo/movies_actor_info.yaml'\n  responses:\n    200:\n      description: list of movies\n      x-walder-input-text/html: movies.pug\n\n```\n\n### Content negotiation\n\nUsing content negotiation, \nWalder makes the following output formats available:\n\n* 'text/html'\n* 'application/ld+json'\n* 'text/turtle'\n* 'application/n-triples'\n* 'application/n-quads'\n\n#### RDF\n\nWalder uses [graphql-ld-comunica](https://www.npmjs.com/package/graphql-ld-comunica) \nto execute the GraphQL queries\nand [@comunica/query-sparql](https://github.com/comunica/comunica/tree/master/engines/query-sparql) \nto execute SPARQL queries.\nThe result of a GraphQL-LD query is a JSON data. \nWalder first converts it into JSON-LD. \nThis enables conversion to other RDF formats during content negotiation.\nThe result of a SPARQL query is an array of quads.\nIf a JSON-LD frame is specified, the quads are converted to JSON-LD.\nDue to the importance of content negotiation,\nonly CONSTRUCT queries are supported.\n\n### HTML templates\n\nWalder uses [consolidate](https://www.npmjs.com/package/consolidate) \nto automatically retrieve the corresponding engine for a given template. \nThis means that the [supported template engines](https://www.npmjs.com/package/consolidate#supported-template-engines) \nare dependent on consolidate.\n\nYou can use different template engines for different routes, e.g., \n[pug](https://pugjs.org/api/getting-started.html) renders one route's HTML, \nwhile [handlebars](https://handlebarsjs.com/) renders another route's HTML. \nWalder does this all by looking at the file extension of the given template.\n\nTemplates can be used in views as well as in layouts. So we'll name them **view templates** and **layout templates** in order to distinguish.\n\n#### Accessing query results in view templates\n\nThe results of the queries, specified in the configuration file for a route, \nare available for rendering in view templates as data.\n- If the route only has a single query, the data contains an object named `data`.\n- If the route has multiple queries, \neach query's result is available in the data as a separate object \nwhose name equals the query name in the configuration file.\n\nIn the case of a GraphQL-LD query,\neach object will be an array, \nunless the query was [singularized](https://github.com/rubensworks/graphql-to-sparql.js#singularizing-everything).\n[songs.handlebars](example/views/songs.handlebars) is an example of the consumption of the result\nof the single query in the route `/music/{musician}` in [this configuration file](example/config.yaml).\n[songs_movies.handlebars](example/views/songs_movies.handlebars) is an example of the consumption of the results\nof the two queries in the route `/artist/{artist}` in [this configuration file](example/config-multiple-queries.yaml).\n\nIn the case of a SPARQL query, \neach object is an array of quads if no JSON-LD frame is specified.\nElse it will be a JSON-LD object.\n\n#### Using layouts in view templates\n\nUsing layouts is a great way to avoid repetition in route-specific view templates.\nReusable HTML structures such as headers, footers, navigation bars and other contents, meant to appear in multiple routes,\nare preferable specified in *layout files*.\n\nA layout template file can be specified in a view template file, \nby means of [front-matter](https://github.com/jxson/front-matter) metadata field `layout`.\nIt should contain a filename, available at the `layouts` location defined in the configuration file.\nIt may contain a relative path in front of the filename.\n\nExample view template file specifying a layout:\n```\n---\nlayout: my-layout.pug\n---\n// view template continues here\n```\n\nWalder puts the inner HTML contents generated from the view template file into the data forwarded to \nthe layout template file as an object named `content`.\n\nThe layout template file is yet another template. \nIt usually expands these inner HTML contents at the position of its choice.\n\nA simple *pug* example (mind the `!{content}`):\n```\ndoctype html\nhtml(lang=\"en\")\n    head\n        title I'm based on a layout\n    body !{content}\n```\n\n#### Accessing front-matter metadata in view templates and layout templates\n\nIn addition to query results, Walder adds [front-matter](https://github.com/jxson/front-matter) metadata,\nspecified in view templates, as additional attributes to the data.\n\nEach additional attribute's name is equal to the metadata field name provided.\nThe following metadata field are reserved: `layout`, `content`, `data`, and \nthe names assigned to queries in routes having multiple queries (see above).\n\nThese attributes are available to the view template and to the layout template it refers to, if any.\n\nExample view template file specifying a front-matter metadata field and reading that field (mind the `#{a1}`):\n```\n--\na1: Value for FrontMatter attribute a1!\n---\n\ndoctype html\nhtml(lang=\"en\")\n    body\n        main a1: #{a1}\n```\n\nExample view template file, specifying a layout template and another front-matter metadata field:\n```\n---\nlayout: layout-fm.pug\na2: Value for FrontMatter attribute a2!\n---\n\nmain Lorem ipsum\n```\n\nExample corresponding layout template (layout-fm.pug) reading that field (mind the `#{a2}`):\n```\ndoctype html\nhtml(lang=\"en\")\n    head\n        if a2\n            title #{a2}\n    body !{content}\n```\n\n## Input validation\n\nWhile parsing the config file, \nWalder also validates the correctness and completeness of the input.\nWhen Walder has parsed the whole config file and found errors, \nWalder returns all errors and exits.\n \nAt the moment, Walder validates the following:\n\n- The config files describe all variables in the query in the parameters section.\n- The config files mention only existing files in `200~x-walder-input-text/html` entries.\n\n## Error handling\n\nWalder binds error pages to a certain HTTP status code. \nYou can define default error pages, \nbut also path specific error pages by adding them to the `responses` key in the corresponding path entry.\n\n### Errors\n\n#### Global\n\n* Error `404`: Page not found\n* Error `500`: Internal server error\n\n#### Pipe modules\n\n* Error `500`: Could not apply the given pipe modules\n\n#### GraphQL-LD\n\n* Error `404`: Expected variable was not given\n* Error `500`: Could not execute the given query\n\n### Example\n\nWhen you run Walder using the following command:\n\n`$ walder -c example/config-errors.yaml`\n\nthe following paths lead to errors:\n\n* \u003chttp://localhost:3000/thisPageSurelyWontExist\u003e \u0026rarr; error `404` (Global: Page not found)\n* \u003chttp://localhost:3000/bad_pipeModule\u003e \u0026rarr; error `500` (Pipe modules: Could not apply the given pipe modules)\n* \u003chttp://localhost:3000/bad_query\u003e \u0026rarr; error `500` (GraphQL-LD: Could not execute the given query)\n\nThe following config file excerpt will use the path specific `moviesServerError.handlebars` view template on errors leading to status code `500` when navigating to `/movies`.\n\nWhen the required query parameter `actor` is not passed, Walder returns the status code `404`. \nWalder will use the default `error404.html` file since the config file has no path-specific HTML view template for the corresponding status.\n\n```yaml\n...\npaths:\n  /movies:\n    get:\n      summary: Returns a list of the all movies the given actor stars in\n      parameters:\n        - in: query\n          name: actor\n          schema:\n            type: string\n            minimum: 0\n          description: The actor from whom the movies are requested\n          required: true\n      x-walder-query:\n        graphql-query: \u003e\n          {\n            id @single\n            ... on Film {\n              starring(label: $actor) @single\n            }\n          }\n        json-ld-context: \u003e\n          {\n            \"@context\": {\n              \"Film\": \"http://dbpedia.org/ontology/Film\",\n              \"label\": { \"@id\": \"http://www.w3.org/2000/01/rdf-schema#label\", \"@language\": \"en\" },\n              \"starring\": \"http://dbpedia.org/ontology/starring\"\n            }\n          }\n      responses:\n        200:\n          description: list of movies\n          x-walder-input-text/html: movies.pug\n        500:\n          description: internal movie server error\n          x-walder-input-text/html: moviesServerError.handlebars\nx-walder-errors:\n  404:\n    description: page not found error\n    x-walder-input-text/html: error404.html\n  500:\n    description: internal server error\n    x-walder-input-text/html: error500.html\n```\n\n## Developing your website\n\nWhilst developing your website,\nyou probably want your website to reload while making changes to `config.yaml`.\nYou can easily do this using [npm-watch](https://www.npmjs.com/package/npm-watch).\nSee the `package.json` snippet below on how to start\n\n```json\n{\n  \"watch\": {\n    \"run\": \"config.yaml\"\n  },\n  \"scripts\": {\n    \"run\": \"walder -c config.yaml --no-cache\",\n    \"watch\": \"npm-watch\"\n  },\n  \"dependencies\": {\n    \"walder\": \"^2.0.1\"\n  },\n  \"devDependencies\": {\n    \"npm-watch\": \"^0.7.0\"\n  }\n}\n```\n\nRun `npm run watch` and Walder reloads every `config.yaml` change!\n\n## Dependencies\n\n| Library | License |\n| ------- | ------- |\n| [@comunica](https://github.com/comunica/) | MIT |\n| [accepts](https://www.npmjs.com/package/accepts) | MIT\n| [axios](https://www.npmjs.com/package/axios) | MIT\n| [chai](https://www.npmjs.com/package/chai) | MIT\n| [commander](https://www.npmjs.com/package/commander) | MIT |\n| [consolidate](https://www.npmjs.com/package/consolidate) | MIT |\n| [debug](https://www.npmjs.com/package/debug) | MIT |\n| [express](https://www.npmjs.com/package/express) | MIT |\n| [front-matter](https://www.npmjs.com/package/front-matter) | MIT |\n| [fs-extra](https://www.npmjs.com/package/fs-extra) | MIT |\n| [graphql-ld](https://www.npmjs.com/package/graphql-ld) | MIT |\n| [graphql-ld-comunica](https://www.npmjs.com/package/graphql-ld-comunica) | MIT |\n| [handlebars](https://www.npmjs.com/package/handlebars) | MIT |\n| [is-html](https://www.npmjs.com/package/is-html) | MIT |\n| [jade-to-handlebars](https://www.npmjs.com/package/jade-to-handlebars) | MIT |\n| [json-refs](https://www.npmjs.com/package/json-refs) | MIT |\n| [jsonld](https://www.npmjs.com/package/jsonld) | BSD-3-Clause |\n| [jsonpath](https://www.npmjs.com/package/jsonpath) | MIT |\n| [markdown-it](https://www.npmjs.com/package/markdown-it) | MIT |\n| [mocha](https://www.npmjs.com/package/mocha) | MIT |\n| [morgan](https://www.npmjs.com/package/morgan) | MIT |\n| [n3](https://www.npmjs.com/package/n3) | MIT |\n| [object-path](https://www.npmjs.com/package/object-path) | MIT |\n| [pug](https://www.npmjs.com/package/pug) | MIT |\n| [supertest](https://www.npmjs.com/package/supertest) | MIT |\n| [tmp](https://www.npmjs.com/package/tmp) | MIT |\n| [winston](https://www.npmjs.com/package/winston) | MIT |\n| [yaml](https://www.npmjs.com/package/yaml) | ISC |\n\n## Tests\n\n* Test framework: [Mocha](https://www.npmjs.com/package/mocha)\n* BDD / assertion library: [Chai](https://www.npmjs.com/package/chai)\n* HTTP assertions: [SuperTest](https://www.npmjs.com/package/supertest)\n\n## Built with Walder\n\n- [KNoWS](https://knows.idlab.ugent.be)\n\nDid you build something Walder and\nwant to add it to the list?\nPlease create a pull request! \n\n## License\nThis code is copyrighted ©2019–2020 by [Ghent University – imec](http://idlab.ugent.be/)\nand released under the [MIT license](http://opensource.org/licenses/MIT).\n\n","funding_links":[],"categories":["website"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FKNowledgeOnWebScale%2Fwalder","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FKNowledgeOnWebScale%2Fwalder","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FKNowledgeOnWebScale%2Fwalder/lists"}