{"id":13555421,"url":"https://github.com/solid-contrib/solid-client","last_synced_at":"2025-04-03T08:31:11.552Z","repository":{"id":57365860,"uuid":"47980444","full_name":"solid-contrib/solid-client","owner":"solid-contrib","description":"Javascript client library for Solid applications","archived":true,"fork":false,"pushed_at":"2021-02-24T19:06:35.000Z","size":941,"stargazers_count":76,"open_issues_count":20,"forks_count":23,"subscribers_count":32,"default_branch":"main","last_synced_at":"2024-05-06T15:15:14.034Z","etag":null,"topics":["running-code"],"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/solid-contrib.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-12-14T14:38:47.000Z","updated_at":"2023-06-02T06:40:54.000Z","dependencies_parsed_at":"2022-08-23T20:10:29.831Z","dependency_job_id":null,"html_url":"https://github.com/solid-contrib/solid-client","commit_stats":null,"previous_names":["solid/solid-client"],"tags_count":58,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/solid-contrib%2Fsolid-client","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/solid-contrib%2Fsolid-client/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/solid-contrib%2Fsolid-client/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/solid-contrib%2Fsolid-client/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/solid-contrib","download_url":"https://codeload.github.com/solid-contrib/solid-client/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246965644,"owners_count":20861904,"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":["running-code"],"created_at":"2024-08-01T12:03:12.168Z","updated_at":"2025-04-03T08:31:08.210Z","avatar_url":"https://github.com/solid-contrib.png","language":"JavaScript","readme":"# solid-client\n[![](https://img.shields.io/badge/project-Solid-7C4DFF.svg?style=flat)](https://github.com/solid/solid)\n[![NPM Version](https://img.shields.io/npm/v/solid-client.svg?style=flat)](https://npm.im/solid-client)\n[![Build Status](https://travis-ci.org/solid/solid-client.svg?branch=master)](https://travis-ci.org/solid/solid-client)\n\n## NOT SUPPORTED - PLEASE USE [solid-auth-client](https://github.com/solid/solid-auth-client)\n\nJavascript library for writing [Solid](https://github.com/solid/solid)\napplications. (See **[Changelog](CHANGELOG.md)** for version history.)\n\n## Usage\n\nThe solid client can be used by solid applications that run in the browser or on\nNode.js. A minified UMD bundle is provided along with the regular set of\nCommonJS modules.\n\nFor example:\n\n```html\n\u003c!DOCTYPE HTML\u003e\n\u003chtml\u003e\n  \u003chead\u003e\n    \u003cscript src=\"dist/solid-client.min.js\"\u003e\u003c/script\u003e\n  \u003c/head\u003e\n  \u003cbody\u003e\n    \u003cscript\u003e\n      var solid = SolidClient\n    \u003c/script\u003e\n  \u003c/body\u003e\n\u003c/html\u003e\n```\n\nOr, using a module loader:\n\n```js\nvar solid = require('solid-client')\n```\n\nSee the [installation docs](docs/installing.md) for more installation examples.\n\nTake a look at the **[solid-client demo\npage](https://solid.github.io/solid-client/demo/)** (source located in\n`demo/index.html`) for usage examples.\n\n## Tutorials\n\nIf you would like to learn how to build Solid apps using solid-client, please see:\n\n* [solid introduction tutorial](https://github.com/solid/solid-tutorial-intro)\n* [pastebin example tutorial](https://github.com/solid/solid-tutorial-pastebin)\n* [using rdflib.js tutorial](https://github.com/solid/solid-tutorial-rdflib.js)\n\n## Developing solid-client\n\n**Node version:** 6.0+.\n\nInstall dev dependencies:\n\n```\nnpm install\n```\n\nBuilding (uses Browserify, builds to `solid-client.js` and `dist/solid-client-no-rdflib.js`):\n\n```\nnpm run build\n```\n\n## Testing\n\nTo run the unit tests:\n\n```\nnpm test\n```\n\nThis runs the [Tape](https://github.com/substack/tape) unit test suite.\n\n## Releases\n\nThe following steps specify how to release solid-client:\n\nMake sure you're at the HEAD of `master`.\n\n```shell\n$ git checkout master \u0026\u0026 git pull\n```\n\nRun `npm version` to bump the package version via git commit and git\ntags.\n\n```shell\n# refer to http://semver.org/ for which of (major, minor, patch) to use\n$ npm version [major|minor|patch]\n```\n\nNext, push the commit and tags:\n\n```shell\n$ git push --follow-tags\n```\n\nFinally release the package to `npmjs`.\n\n```shell\n$ npm publish\n```\n\n## Logging In and User Profiles\n\nBefore doing any sort of [reading or\nwriting](https://github.com/solid/solid-spec#reading-and-writing-resources) of\nSolid resources, your app will likely need to authenticate a user and load their\nprofile, so let's start with those sections.\n\n### Authentication\n\nSolid currently uses [WebID-TLS](https://github.com/solid/solid-spec#webid-tls)\nfor authentication, which relies on a web browser's built-in key store to manage\ncertificates and prompt the user to select the correct certificate when\naccessing a server.\n\nSolid servers must always return a Solid-specific HTTP header called `User`,\nwhich contains the [WebID](https://github.com/solid/solid-spec#identity) that\nthe user used to access this particular server. An empty header usually means\nthat the user is not authenticated.\n\n#### Detecting the Current Logged-in User\n\nMost of the WebID-TLS authentication process takes place before a web\npage gets fully loaded and the javascript code has had a chance to run.\nSince client-side Javascript code does *not* have access to most HTTP headers\n(including the `User` header) of the page on which it runs, how does an app\ndiscover if there is an already authenticated user that is accessing it?\n\nThe current best practice answer is -- the app should do an Ajax/XHR HEAD\nrequest to the relevant resource:\n\n1. either to the *current page* if it's a standalone app, or\n2. to the requested resource (if it's an app that's acting as a viewer or\n  editor, and requires a resource URI as a parameter)\n\nFor the first case (standalone apps), solid-client provides a convenience\n`solid.currentUser()` method (which does a HEAD request to the current page in\nthe background). Usage:\n\n```js\nsolid.currentUser()\n  .then(function (currentWebId) {\n    if (currentWebId) {\n      console.log('Current WebID: %s', currentWebId)\n    } else {\n      console.log('You are not logged in')\n    }\n  })\n```\n\nFor the second case (apps that are wrapping a resource as viewers or editors),\nclient apps can just use a `solid.login(targetUrl)` function to return the\ncurrent user's WebID. And if users are unable to log in, prompt the user\nto create an account with `solid.signup()`.\n\n#### Login example\n\nHere is a typical example of authenticating a user and returning their WebID.\nThe following `login` function, specific to your application, wraps the\n`solid.login()` function. If the promise is resolved, then an application\nwill do something with the `webId` value. Otherwise, if the promise is rejected,\nthe application may choose to display an error message.\n\nHTML:\n\n```html\n\u003ca href=\"#\" onclick=\"login()\"\u003eLogin\u003c/a\u003e\n```\n\nJavascript:\n\n```javascript\nvar solid = require('solid')\nvar login = function() {\n  // Get the current user\n  solid.login().then(function (webId){\n    // authentication succeeded; do something with the WebID string\n    console.log(webId)\n  }).catch(function (err) {\n    // authentication failed; display some error message\n    console.log(err)\n  })\n}\n```\n\n### Signup example\n\nThe `signup` function is very similar to the `login` function, wrapping the\n`solid.signup()` function. It results in either a WebID or an error message\nbeing returned.\n\nHTML:\n\n```html\n\u003ca href=\"#\" onclick=\"signup()\"\u003eSign up\u003c/a\u003e\n```\n\nJavascript:\n\n```javascript\nvar solid = require('solid')\n// Signup for a WebID\nvar signup = function() {\n  solid.signup()\n    .then(function (webId) {\n      // authentication succeeded; do something with the WebID string\n      console.log(webId)\n    })\n    .catch(function (err) {\n      // authentication failed; display some error message\n      console.log(err)\n    })\n}\n```\n\n### User Profiles\n\nOnce you have a user's WebID (say, from a `login()` call), it's often useful\nto load the user profile:\n\n```javascript\nvar profile = solid.login()\n  .then(function (webId) {\n    // have the webId, now load the profile\n    return solid.getProfile(webId)\n  })\n```\n\nThe call to `getProfile(url)` loads the full [extended\nprofile](https://github.com/solid/solid-spec/blob/master/solid-webid-profiles.md#extended-profile):\nthe profile document itself, any `sameAs` and `seeAlso` links it finds there,\nas well as the Preferences file.\n\nOnce a profile is loaded, you can access the values of the profile's pre-defined\nfields, or look for predicates in the profile's parsed graph using\n`profile.find()` and `profile.findAll()`:\n\n```js\nvar ns = solid.vocab\nsolid.login()\n  .then(function (webId) {\n    return solid.getProfile(webId)\n  })\n  .then(function (profile) {\n    profile.name  // -\u003e 'Alice'\n    profile.picture   // -\u003e 'https://example.com/profile/icon.png'\n    profile.find(ldp.solid('inbox'))    // -\u003e 'https://example.com/inbox/'\n    profile.findAll(ns.owl('sameAs'))  // -\u003e [ url1, url2 ]\n  })\n  .catch(function (err) {\n    console.log('Error accessing profile: ' + err)\n  })\n```\n\n#### Profile App Registry\n\nThe profile provides an interface to the user's App Registry.\n\n```js\nvar ns = solid.vocab\nsolid.login()\n  .then(function (webId) {\n    return solid.getProfile(webId)\n  })\n  .then(function (profile) {\n    return profile.loadAppRegistry()\n  })\n  .then(function (profile) {\n    // The profile has been updated, app registry loaded. Now you can register\n    // apps with is.\n    var options = {\n      name: 'Contact Manager',\n      shortdesc: 'A reference contact manager',\n      redirectTemplateUri: 'https://solid.github.io/contacts/?uri={uri}'\n    }\n    var typesForApp = [ ns.vcard('AddressBook') ]\n    var isListed = true\n    var app = new AppRegistration(options, typesForApp, isListed)\n    return profile.registerApp(app)\n  })\n  .then(function (profile) {\n    // The app entry was created. You can now query the registry for it\n    return profile.appsForType(ns.vcard('AddressBook'))\n  })\n  .then(function (registrationResults) {\n    var app = registrationResults[0]\n    app.name  // -\u003e 'Contact Manager'\n    app.shortdesc  // -\u003e ...\n    app.redirectTemplateUri\n  })\n```\n\n#### User Type Registry Index\n\nIf your application needs to do data discovery, it can also call\n`loadTypeRegistry()` after loading the profile:\n\n```javascript\nvar profile = solid.login()\n  .then(function (webId) {\n    return solid.getProfile(webId)\n  })\n  .then(function (profile) {\n    return profile.loadTypeRegistry()\n  })\n```\n\nNow, both listed and unlisted type indexes are loaded, and you can look up\nwhere the user keeps various types.\n\n```js\nvar ns = solid.vocab\n// .. load profile and load type registry\n\nvar addressBookRegistrations = solid.getProfile(webId)\n  .then(function (profile) {\n    return profile.loadTypeRegistry()\n  })\n  .then(function (profile) {\n    return profile.typeRegistryForClass(ns.vcard('AddressBook'))\n  })\n/*\n--\u003e\n[\n  an IndexRegistration(\n    locationUri: 'https://localhost:8443/public-contacts/AddressBook.ttl',\n    locationType: 'instance',\n    isListed: true\n  ),\n  an IndexRegistration(\n    locationUri: 'https://localhost:8443/personal-address-books/',\n    locationType: 'container',\n    isListed: false\n  )\n]\n*/\n```\n\nYou can then load the resources from the returned locations, as usual.\n\n```js\naddressBookRegistrations.forEach(function (registration) {\n  if (registration.isInstance()) {\n    // This is an instance (an individual resource)\n  } else if (registration.isContainer()) {\n    // This is a container with many address books\n  }\n})\n```\n\n#### Registering (and un-registering) Types in the Type Registry\n\nTo register an RDF Class with a user's Type Registry (listed or unlisted),\nuse `profile.registerType()`:\n\n```js\nvar ns = solid.vocab\n// .. load profile\n\nvar classToRegister = vocab.sioc('Post')\nvar locationToRegister = 'https://localhost:8443/new-posts-container/'\nvar isListed = true\nprofile.registerType(classToRegister, locationToRegister, 'container', isListed)\n  .then(function (profile) {\n    // Now the type is registered, and the profile's type registry is refreshed\n    // querying the registry now will include the new container\n    profile.typeRegistryForClass(ns.sioc('Post'))\n  })\n\n// To remove the same class from registry:\nvar classToRemove = ns.sioc('Post')\nprofile.unregisterType(classToRemove, isListed)\n  .then(function (profile) {\n    // Type is removed\n    profile.typeRegistryForClass(ns.sioc('Post'))   // --\u003e []\n  })\n```\n\n## Web operations\n\nsolid-client uses a mix of [LDP](http://www.w3.org/TR/ldp/) and Solid-specific\nfunctions to manipulate Web resources. Please see the\n[Solid spec](https://github.com/solid/solid-spec) for more details.\n\n### Getting information about a resource\n\nSometimes an application may need to get some useful meta data about a resource.\nFor instance, it may want to find out where the ACL resource is. Clients should\ntake notice to the fact that the `solid.web.head()` function will always\nsuccessfully complete, even for resources that don't exists, since that is\nconsidered useful information. For instance, clients can use the\n`solidResponse.xhr.status` value will indicate whether the resource exists or\nnot.\n\nHere, for example, we can find out where the corresponding ACL resource is for\nour new blog post `hello-world`.\n\n```javascript\nvar solid = require('solid')\nvar url = 'https://example.org/blog/hello-world'\nsolid.web.head(url).then(\n  function(solidResponse) {\n    console.log(solidResponse.acl) // the ACL uri\n    if (!solidResponse.exists()) {\n      console.log(\"This resource doesn't exist\")\n    } else if (solidResponse.xhr.status === 403) {\n      if (solidResponse.isLoggedIn()) {\n        console.log(\"You don't have access to the resource\")\n      } else {\n        console.log(\"Please authenticate\")\n      }\n    }\n  }\n)\n```\n\nThe `SolidResponse` object returned by most `solid.web` calls, including\n`head()`, contains the following properties:\n\n* `url` - the URL of the resource // `https://example.org/blog/hello-world`\n* `acl` - the URL of the corresponding .acl resource  //\n  `https://example.org/blog/hello-world.acl`\n* `meta` - the URL of the corresponding .meta resource //\n  `https://example.org/blog/hello-world.meta`\n* `types` - An array of LDP types for the resource, if applicable. For example:\n    `[ 'http://www.w3.org/ns/ldp#LDPResource',\n       'http://www.w3.org/ns/ldp#Resource' ]`\n* `user` - the WebID of the authenticated user (if authenticated) //\n  `https://user.example.org/profile#me`\n* `websocket` - the URI of the corresponding websocket instance //\n  `wss://example.org/blog/hello-world`\n* `method` - the HTTP verb (`get`, `put`, etc) of the original request that\n  resulted in this response.\n* `xhr` - the raw XMLHttpRequest object (e.g. xhr.status)\n\nThe response object also has some convenience methods:\n\n* `contentType()` - returns the MIME type of the resource\n* `isContainer()` - determines whether the resource is a Container or a regular\n    resource\n\n### Fetching a Resource\n\nAssuming that a resource or a container exists (see\n[creating resources](#creating-a-resource) and\n[creating containers](#creating-a-solid-container) below), you can retrieve\nit using `web.get()`:\n\n```js\nsolid.web.get(url)\n  .then(function (response) {\n    if (response.isContainer()) {\n      // This is an instance of SolidContainer, see Listing Containers below\n      for (resourceUrl in response.resources) {\n        // iterate over resources\n      }\n      for (subcontainerUrl in response.containers) {\n        // iterate over sub-containers\n      }\n    } else {\n      // Regular resource\n      console.log('Raw resource: %s', response.raw())\n\n      // You can access the parsed graph (parsed by RDFLib.js):\n      var parsedGraph = response.parsedGraph()\n    }\n  })\n  .catch(function (err) {\n      console.log(err) // error object\n    // ...\n   })\n```\n\n#### Fetching a Parsed Graph\n\nOnce a resource is retrieved, we can access it as a parsed graph (here, parsed\nby `rdflib.js`). This graph can then be queried.\n\n```js\nvar solid = require('solid')\nvar vocab = solid.vocab\n\nvar url = 'https://example.org/blog/hello-world'\n\nsolid.web.get(url)\n  .then(function(response) {\n    var graph = response.parsedGraph()\n    // Print all statements matching resources of type foaf:Post\n    console.log(graph.statementsMatching(undefined, vocab.rdf('type'),\n      vocab.sioc('Post')))\n  })\n  .catch(function(err) {\n    console.log(err) // error object\n  })\n```\n\n### Creating a Solid Container\n\nThe Solid client offers a function called `solid.web.createContainer()`,\nwhich is used to create containers. The\nfunction accepts the following parameters:\n\n* `parentDir` (string) - the URL of the parent container in which the new\n  resource/container will be created.\n* `containerName` (string) (optional) - the value for the `Slug` header -- i.e. the name\n  of the new resource to be created; this value is optional.\n* `options` (object) - Optional hashmap of request options\n* `data` (string) - Optional RDF data serialized as `text/turtle`; can also be an empty\n  string if no data will be sent.\n\nIn the example below we are also sending some meta data (semantics) about the\ncontainer, setting its type to `sioc:Blog`.\n\n```javascript\n// Assumes you've loaded rdflib.js and solid-client, see Dependences above\nvar solid = require('solid')\nvar parentUrl = 'https://example.org/'\nvar containerName = 'blog'\nvar options = {}\nvar data = '\u003c#this\u003e \u003chttp://www.w3.org/1999/02/22-rdf-syntax-ns#type\u003e \u003chttp://rdfs.org/sioc/ns#Blog\u003e .'\n\nsolid.web.createContainer(parentUrl, containerName, options, data).then(\n  function(solidResponse) {\n    console.log(solidResponse)\n    // The resulting object has several useful properties.\n    // See lib/solid/response.js for details\n    // solidResponse.url - value of the Location header\n    // solidResponse.acl - url of acl resource\n    // solidResponse.meta - url of meta resource\n  }\n).catch(function(err){\n  console.log(err) // error object\n})\n```\n\nNote that the `options` and `data` parameters are optional, and you can simply\ndo `solid.web.createContainer(url, name)`.\n\n### Listing a Solid Container\n\nTo list the contents of a Solid container, just use `solid.web.get()`.\nThis returns a promise that resolves to a `SolidContainer` instance,\nwhich will contain various useful properties:\n\n- A short name (`.name`) and absolute URI (`.uri`)\n- A `.parsedGraph` property for further RDF queries\n- A parsed list of links to all the contents (both containers and resources)\n  (`.contentsUris`)\n- A list of RDF types to which the container belongs (`.types`)\n- A hashmap of all sub-Containers within this container, keyed by absolute uri\n  (`.containers`)\n- A hashmap of all non-container Resources within this container, also keyed by\n  absolute uri. (`.resources`)\n\nContainers also have several convenience methods:\n\n- `container.isEmpty()` will return `true` when there are no sub-containers or\n  resources inside it\n- `container.findByType(rdfClass)` will return an array of resources or\n  containers that have the given `rdfClass` in their `.types` array\n\nFor example:\n\n```js\nvar container = solid.web.get('/settings/')\n                  .then(function (container) {\n                    console.log(container)\n                    // See below\n                  })\n\n// container is an instance of SolidContainer (see lib/solid/container.js)\ncontainer.uri   // -\u003e 'https://localhost:8443/settings/'\ncontainer.name  // -\u003e 'settings'\ncontainer.isEmpty()  // -\u003e false\ncontainer.types // -\u003e\n[\n  'http://www.w3.org/ns/ldp#BasicContainer',\n  'http://www.w3.org/ns/ldp#Container'\n]\ncontainer.contentsUris // -\u003e\n[\n  'https://localhost:8443/settings/prefs.ttl',\n  'https://localhost:8443/settings/privateTypeIndex.ttl',\n  'https://localhost:8443/settings/testcontainer/'\n]\n\nvar subContainer =\n    container.containers['https://localhost:8443/settings/testcontainer/']\nsubContainer.name // -\u003e 'testcontainer'\nsubContainer.types // -\u003e\n[\n  'http://www.w3.org/ns/ldp#BasicContainer',\n  'http://www.w3.org/ns/ldp#Container',\n  'http://www.w3.org/ns/ldp#Resource'\n]\n\nvar resource =\n  container.resources['https://localhost:8443/settings/privateTypeIndex.ttl']\n// resource - SolidResource instance\nresource.name // -\u003e 'privateTypeIndex.ttl'\nresource.types // -\u003e\n[\n  'http://www.w3.org/ns/ldp#Resource',\n  'http://www.w3.org/ns/solid/terms#TypeIndex',\n  'http://www.w3.org/ns/solid/terms#UnlistedDocument'\n]\nresource.isType('http://www.w3.org/ns/solid/terms#TypeIndex')  // -\u003e true\n\ncontainer.findByType('http://www.w3.org/ns/ldp#Resource')  // -\u003e\n[\n  // a SolidContainer('testcontainer'),\n  // a SolidResource('privateTypeIndex.ttl'),\n  // a SolidResource('prefs.ttl')\n]\n```\n\n### Creating a resource\n\nCreating a regular LDP resource is done using the `web.post()` method.\n\nIn this example we will create the resource `hello-world` under the newly\ncreated `blog/` container.\n\n```javascript\nvar solid = require('solid')\nvar parentDir = 'https://example.org/blog/'\nvar slug = 'hello-world'\nvar data = `\n\u003c\u003e a \u003chttp://rdfs.org/sioc/ns#Post\u003e ;\n    \u003chttp://purl.org/dc/terms/title\u003e \"First post\" ;\n    \u003chttp://rdfs.org/sioc/ns#content\u003e \"Hello world! This is my first post\" .\n`\n\nsolid.web.post(parentDir, data, slug)\n  .then(function (response) {\n    console.log(response.url) // URL of the newly created resource\n  })\n  .catch(function (err){\n    console.log(err) // error object\n  })\n```\n\n### Updating a resource\n\nSometimes we need to update a resource after making a small change. For\ninstance, we sometimes need to delete a triple, or update the value of an object\n(technically by replacing the triple with a new one). Luckily, Solid allows us\nto use the `HTTP PATCH` operation to do very small changes.\n\nLet's try to change the value of the title in our first post. To do so, we need\nto indicate which triple we want to replace, and then the triple that will\nreplace it.\n\nLet's create the statements and serialize them to Turtle before patching the\nblog post resource:\n\n```js\nvar rdf = require('rdflib')\nvar url = 'https://example.org/blog/hello-world'\nvar vocab = ns.vocab\n\nvar oldTitleTriple = rdf.triple(rdf.namedNode(url), ns.dct('title'),\n  rdf.literal(\"First post\")).toCanonical()\n\nvar newTitleTriple = rdf.triple(rdf.namedNode(url), ns.dct('title'),\n  rdf.literal(\"Hello\")).toCanonical()\n```\n\nNow we can actually patch the resource. The `solid.web.patch()` function (also\naliased to `solid.web.update()`) takes three arguments:\n\n* `url` (string) - the URL of the resource to be overwritten.\n* `toDel` (array) - an array of statements to be deleted, serialized as Turtle.\n* `toIns` (array) - an array of statements to be inserted, serialized as Turtle.\n\n```javascript\nvar solid = require('solid')\nvar toDel = [ oldTitleTriple ]\nvar toIns = [ newTitleTriple ]\nsolid.web.patch(url, toDel, toIns)\n  .then(function (response){\n    console.log(response.xhr.status) // HTTP 200 (OK)\n  })\n  .catch(function(err) {\n    console.log(err) // error object\n  })\n```\n\n### Replacing a resource\n\nWe can also completely replace (overwrite) existing resources with new content,\nusing the client's `solid.web.put()` function (also aliased to `replace()`). The\nfunction accepts the following parameters:\n\n* `url` (string) - the URL of the resource to be overwritten.\n* `data` (string) - RDF data serialized as `text/turtle`; can also be an empty\n  string if no data will be sent.\n* `mime` (string) (optional) - the mime type for this resource; this value is\n  optional and defaults to `text/turtle`.\n\nHere is an example where we try to overwrite the existing resource\n`hello-world`, giving it a bogus type - `http://example.org/#Post`.\n\n```javascript\nvar solid = require('solid')\nvar url = 'https://example.org/blog/hello-world'\nvar data = '\u003c\u003e \u003chttp://www.w3.org/1999/02/22-rdf-syntax-ns#type\u003e \u003chttp://example.org/#Post\u003e .'\n\nsolid.web.put(url, data)\n  .then(function (response) {\n    console.log(response.xhr.status) // HTTP 200 (OK)\n  })\n  .catch(function(err) {\n    console.log(err) // error object\n  })\n```\n\n### Deleting a resource\n\nDelete an RDF resource from the Web. For example, we can delete the blog post\n`hello-world` we created earlier, using the `solid.web.del()` function.\n\n**NOTE:** while this function can also be used to delete containers, it will\nonly work for empty containers. For now, app developers should make sure to\nempty a container by recursively calling this function on its contents.\n\n```javascript\nvar solid = require('solid')\nvar url = 'https://example.org/blog/hello-world'\n\nsolid.web.del(url)\n  .then(function (response) {\n    console.log(response)\n  }).catch(function (err) {\n    console.log(err) // error object\n  })\n```\n\n### Managing Resource Permissions\n\nEach Solid resource has a set of permissions that determine which user\n(identified by their WebID) has read and write access to it, called an\n*ACL resource*.\n(See the [`web-access-control-spec` repo](https://github.com/solid/web-access-control-spec)\nfor the exact details.)\n\nsolid-client has a set of convenience methods to help developers manage those\npermissions.\n\n#### Reading Permissions\n\nTo load the corresponding ACL resource, for a given file:\n\n```js\nvar solid = require('solid')\nvar resourceUrl = 'https://example.org/blog/hello-world'\n\nsolid.getPermissions(resourceUrl)\n  .then(function (permissionSet) {\n    // Now the permission set, parsed from `hello-world.acl` is loaded,\n    // and you can iterate over the individual authorizations\n    permissionSet.forEach(function (auth) {\n      if (auth.isAgent()) {\n        console.log('agent webId: ' + auth.agent)\n      } else if (auth.isPublic()) {\n        // this permission is for everyone (acl:agentClass foaf:Agent)\n      } else if (auth.isGroup()) {\n        console.log('agentClass webId: ' + auth.group)\n      }\n      // You can also use auth.webId() for all cases:\n      console.log('agent/group webId: ' + auth.webId())\n      // You can check what sort of access modes are granted:\n      auth.allowsRead()  // -\u003e true if the authorization contains acl:Read mode\n      auth.allowsWrite()\n      auth.allowsAppend()\n      auth.allowsControl()\n      // Check to see if this Authorization is inherited (`acl:default`)\n      auth.isInherited()  // -\u003e false for a resource, usually true for container\n      // Check to see if access is allowed from a given Origin\n      auth.allowsOrigin('https://example.com')\n    })\n  })\n```\n\n**Note:** You can read the permissions for a given resource *only* if you have\n`acl:Control` access mode for that resource. (You also need that access mode to\nedit those permissions, as well.)\n\nYou can also access individual authorizations from a resource set:\n\n```js\nsolid.getPermissions(resourceUrl)\n  .then(function (permissionSet) {\n    var auth = permissionSet.permissionFor(bobWebId)\n    auth.webId()  // -\u003e bob's web id\n    auth.allowsRead()  // -\u003e true if bob has acl:Read permission\n    auth.allModes()    // -\u003e array of access modes granted\n    auth.allOrigins()  // -\u003e array of allowed origin URLs\n    // If this is for the root container's ACL, you can also load a user's\n    // emails using the `mailTo` property. (Unofficial functionality)\n    auth.mailTo  // -\u003e ['bob@example.com', 'bob@gmail.com']\n  })\n```\n\n#### Editing Permissions\n\nTo manage the set of permissions for a given resource (provided the current\nuser has `acl:Control` access mode granted to them for that resource), use\nthe convenience methods provided by `PermissionSet`.\n\nThe example below adds 3 different permissions:\n\n1. Allows Alice to Read, Write and Control the resource\n2. Allows Public Read access (that's the `solid.acl.EVERYONE`)\n3. Grants Bob Write access (in addition to the Read access he inherits from\n   the above permission, since he's a member of the Public).\n   Also, this Write access is only allowed from a particular *origin*.\n\n```js\nvar solid = require('solid')\nvar resourceUrl = 'https://example.org/blog/hello-world'\nvar aliceWebId = 'https://alice.example.org/profile/card#me'\nvar bobWebId = 'https://bob.example.org/profile/card#me'\nvar allowedOrigin = 'https://example.org'\n\nsolid.getPermissions(resourceUrl)\n  .then(function (permissionSet) {\n    return permissionSet\n      .addPermission(aliceWebId, [solid.acl.READ, solid.acl.WRITE,\n        solid.acl.CONTROL])\n      .addPermission(solid.acl.EVERYONE, solid.acl.READ)\n      // see also .addGroupPermission()\n      .addPermission(bobWebId, solid.acl.WRITE, allowedOrigin)\n      .save()\n  })\n  .then(function (response) {\n    console.log('Permissions saved successfully')\n  })\n  .catch(function (err) {\n    console.log('Error saving permissions')\n  })\n```\n\nTo *delete* all permissions associated with a resource, use\n`clearPermissions()`. Keep in mind that permissions are inherited from a\nresource's parent container, and if you delete an individual ACL resource,\nthis simply means that the permissions reset to that of the upstream container.\nYou can also clear the ACLs of the container, all the way up to the root storage\ncontainer's ACL, which cannot be deleted. Refer to the\n[ACL Inheritance Algorithm](https://github.com/solid/web-access-control-spec#acl-inheritance-algorithm)\nsection of the spec.\n\n```js\n// If you have an existing PermissionSet as a result of `getPermissions()`:\nsolid.getPermissions('https://www.example.com/file1')\n  .then(function (permissionSet) {\n    return permissionSet.clear()  // deletes the file1.acl resource\n  })\n// Otherwise, use the helper function\n//   solid.clearPermissions(resourceUrl) instead\nsolid.clearPermissions('https://www.example.com/file1')\n  .then(function (response) {\n    // file1.acl is now deleted\n  })\n```\n","funding_links":[],"categories":["JavaScript","others"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsolid-contrib%2Fsolid-client","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsolid-contrib%2Fsolid-client","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsolid-contrib%2Fsolid-client/lists"}