This project adheres to Semantic Versioning.
The following changes are pending, and will be applied on the next major release:
2.1.2 - 2024-10-15
- This release has no impact on shipped code. A missing feature flag has been added to Problem Details end-to-end tests.
2.1.1 - 2024-10-14
- This release has no impact on shipped code. A feature flag has been added to Problem Details end-to-end tests.
2.1.0 - 2024-08-27
- Node 22 is now supported
FetchError
now implementsWithProblemDetails
: it has a.problemDetails
getter providing additional information about the HTTP error response, either provided by the server if it supports RFC9457, or falling back to defaults.
-
Fixed #2339: Unnamed policies are now returned by
getResourcePolicyAll
if an optional argument{ acceptBlankNodes: true }
is specified. This additional argument makes this a non-breaking change, as the current type signature isn't changed. -
getThing
now supports Blank Node identifiers in addition to IRIs and skolems to refer to a subject. -
getThingAll(dataset, { allowacceptBlankNodes: true })
now returns all Blank Nodes subjects in the Dataset, in particular including those part of a single chain of predicates. For instance, given the following dataset:@prefix ex: <https://example.org/> . @prefix foaf: <http://xmlns.com/foaf/0.1/> . ex:camille foaf:knows [ foaf:name "Dominique"@en ; ] . ;
getThingAll(dataset, { allowacceptBlankNodes: true })
would have previously returned a single element for the Named Node (ex:camille
), it will now also include a second element for the Blank Node. Blank Node identifiers are by definition unstable and shouldn't be relied upon beyond local resolution.
The following changes have been implemented but not released yet:
- Normalize input URLs for
getSolidDataset
,getFile
,saveSolidDatasetAt
,overwriteFile
,createContainerAt
,deleteSolidDataset
,deleteFile
,deleteContainer
,saveSolidDatasetInContainer
,createContainerInContainer
,saveFileInContainer
,getResourceInfo
: Input URLs are now normalized by collapsing slash sequences (foo///bar
becomesfoo/bar
), and resolving relative URL segments (foo/bar/..
becomesfoo/
).
- Use the global
fetch
function instead of@inrupt/universal-fetch
. This means this library now only works with Node 18 and higher. - Due to changes in the rollup config the
umd
output is now found atdist/index.umd.js
rather thanumd/index.js
. - Drop support for
Buffer
s as input tosaveFileInContainer
andoverwriteFile
. Use the file name of inputs tosaveFileInContainer
as theSlug
name recommendation if no slug is explicitly provided. - Have
getJsonLdParser
returnvoid
rather than a Promise so that it now aligns with theParser
type definition. - Remove deprecated ACP APIs; including all APIs for ESS 1.1.
- 1549: The universal API had a bug preventing it from handling correctly resources with a missing ACL. This is now resolved, and it correctly proceeds to creating the target ACL if required.
- Add a non-regression test for containment relationship validation. The behavior of the library was already correct in a specific edge case, but that was not covered by any test. Thanks to Otto-AA for noticing the gap and implementing the missing test.
- Build system (bundler and TypeScript) updates. This should be transparent to dependants.
validateContainedResourcesAll
: In addition to the change togetContainedResourcesAll
described in the Bugfix section, a new function is added to the API to help detecting incorrect containment claims.
getProfileAll
now also followsrdfs:seeAlso
when discovering extended profiles.- When listing contained resources with
getContainedResourcesAll
, resources that are not direct child resources of the target container from a URL path semantics perspective are no longer returned. This meanshttps://pod.example.org/foo/bar/moo
cannot be considered a child resource ofhttps://pod.example.org/foo/
, regardless of theldp:contains
statements in the container. Resources from a different origin are also be excluded by this change.
- Support
File
type from@types/node
inoverwriteFile
andsaveFileInContainer
.
Buffer
type: As discussed in microsoft/TypeScript#53668 the @types/node definition of a buffer is looser than the DOM one (the latter being TS' default), and hence we now use that in order to be compatible with web buffer types and node buffer types.
- Node 20 support
universal
: Ignore errors when ACL is not found, so that it can be handled properly for WAC.
- Buffer API marked as deprecated.
- Node 18 support
saveSolidDatasetAt
has a newoptions
field,prefixes
. It allows a prefix map to be passed in to customize the serialization if the target format supports it.
- File APIs marked as stable.
- Add the response body along the status code and text in the error messages thrown on unsuccessful response from the server. The response body may contain additional data useful for the user to have in order to fix the issue the server describes.
- Export the
AccessModes
type from theinterfaces
module.
- Moved
@types/rdfjs__dataset
back to dependencies from devDependencies to fix the issues with TypeScript and related tooling complaining about missing types. This is a temporary fix whilst we work on a more long term solution. We'd initially only thought this issue affected Typedoc, not all TypeScript projects.
- Fixed the changelog data structure creation to avoid potential prototype pollution attacks.
- Fixed the generation of unique identifiers to use UUIDs instead of
Math.random()
. We're also changing generated ACP IRIs to no longer contain identifying information, instead these will just be UUIDs going forwards (some identifying information may still remain, as the ACP algorithm uses suffixes of existing IRIs when making modifications, we've a ticket to address this in the future).
- Set recursive VC access: the
setVcAccess
function (from theacp/acp
module) now has anoptions
object, which includes aninherit
flag. If set totrue
, the newly set VC access applies not only to the target resource, but to its contained resources too.
- Change targeted environment to ES2018
- Dependency updates
- Added
getWebIdDataset
method to fetch the WebId Profile document as a Solid Dataset. This method is part of theprofile/webid
module.
- Export the
WithAcp
andWithAccessibleAcr
types.
- Modify the internal
getWellKnownSolid
method used by@inrupt/solid-client-notifications
to always use the provided fetch implementation when requesting the solid dataset that is the/.well-known/solid
resource. This fixes a bug where in some environments cross-fetch failed to load at this point in the code.
- Remove workaround for creating containers with POST instead of PUT. This was needed for Node Solid Server (version < 5.3)
- Migrate project to our common eslint configuration, this resulted in a fairly large amount of code changes, though everything should appear the same to consumers.
saveSolidDatasetInContainer
andcreateContainerInContainer
adequately take into account the Location header to determine the location of newly created resources.
- Support for Node.js v12.x has been dropped as that version has reached end-of-life.
getWellKnownSolid
fetches well known solid from the server's root by default.
acp_ess_1
&acp_ess_2
export all low level ACP functions available for interacting with Inrupt's ESS ACP implementations.
- Removed
getWellKnownSolid
from public documentation, as this method is too unstable for end-users of the SDK to be using right now.
getAgentAccessAll
has been added to the newuniversal
access module. This function provides an overview of access modes granted to all agents.
getProfileAll
andgetPodUrlAll
no longer make an authenticated request to the WebID profile, which should be a public resource in the first place.
- Export the
Actor
type in theuniversal_v1
module.
getPodUrlAll
no longer throws if the WebID only appears as the object in an alternative profile (and not as a subject), which is a valid case.
-
getAltProfileUrlAllFrom
: A function available in theprofile/webid
module which returns the alternative profiles URLs (if any) from a given WebID profile resource. -
solidDatasetAsTurtle
: A function available in theformats
module which provides turtle serialisation of a solid dataset or part of it.
getProfileAll
no longer throws if fetching one of the alternative profiles fails. Instead, the successfully fetched alternative profiles are returned, and the thrown errors are catched. To use in conjunction withgetAltProfileUrlAllFrom
to figure out if fetching one or more alternative profiles failed. Note that this also resolves this bug in other functions based on this one, such asgetPodUrlAll
.
universalAccess
/universal
: functions available in theuniversal
module or in the library via importinguniversalAccess
work with the latest version of the ACP specification and supersede theaccess/universal
module.
-
The universal access API group functions
getAccessFor
,getAccessForAll
andsetAccessFor
have been deprecated. In order for it to be a non-breaking change, the universal API is now exposed through theuniversal
module. -
The low-level ACP API (V4) will no longer support custom Markdown serialization. That is, the
acrAsMarkdown
,matcherAsMarkdown
,policyAsMarkdown
functions. The API is still experimental and settling it takes priority. Helping users in understanding the structure of any RDF might be improved through better turtle serialisation for example and if we come to natural language, the feature might be given more attention as a generic markdown serialisation framework.
getPodUrlAll
/getPodUrlAllFrom
: functions available in theprofile/webid
module to discover an agent's Pods based on their profiles.
- The ACP v4 low-level API is amended so that new policies use the default access controls.
Implemented
setResourcePolicy
and removed obsoletesetResourceAcrPolicy
.
getVcAccess
/setVcAccess
: functions available in theacp/acp
module to get and set Access Modes for a resource applicable when an Access Grant for the given resource is issued.
- The ACP low-level API is amended to align with the latest specification draft.
-
getProfileAll
: function to discover the WebID Profile Document and its associated FOAF Profile Document resources from the WebID URI. Note that Profile documents may or not be Solid Resources -
Allow
createContainerAt
to take an optional SolidDataset parameter to use as the body of the HTTP request to the server. This is really useful when we wish to include meta-data for a new container, things like a textual label or comment.
getLinkedAcrUrl
returns the URL of an Access Control Resource from the server-managed metadata associated to a given resource.getJsonLdParser
andgetTurtleParser
are experimental functions to explicitly control the RDF serialization of the target ofgetSolidDataset
.
- In some cases, the ACP functions failed to find the Access Control node within an Access Control Resource, leading to policies being unapplied.
- The discovery of the
.well-known/solid
document now supports Pod servers where it is directly available at the domain root, rather than being specific to individual Pod roots.
isAcpControlled
is a function verifying whether a given resource is controlled using ACP. This is useful for apps not yet migrated to the universal API.
- The discovery of the
.well-known/solid
document failed if the Pod server returned a Link to the Pod root missing the trailing slash.
- Getting an authentication failure when looking up metadata necessarily threw an error, which prevented some legitimate use cases, e.g. the Pod root discovery from a given resource.
- The change on
getThingAll
introduced in 1.13.0 was actually breaking for some users, so this makes it opt-in rather than default.
- Added convenience functions 'add/get/set/removeStringEnglish()' and 'add/get/set/removeStringEnglishAll()'. We're still gently expressing the impossible-to-ignore relevance of locales in the underlying RDF (and 'cos trying to 'hide' that critical RDF-ness (e.g., via an implicitly-acting function like addString()) would lead to all sorts of confusion later (i.e., would it add an English language tag, or a NoLocale string literal?)).
getThingAll
used to only return Things that had an IRI, and to ignore Things with a blank node as a subject. This prevents some legitimate use cases, such as parsing the.well-known/solid
document (which only contains one blank node).
- Manage public keys attached to your profile with the functions
addJwkToJwks
,addPublicKeyToProfileJwks
,getProfileJwksIri
andsetProfileJwks
, from the@inrupt/solid-client/profile/jwks
module. - Add
getWellKnownSolid
, to return the contents of the.well-known/solid
endpoint for a given resource url.
- In some cases, Thing.getDate() would return null while Thing.setDate() had been called prior. Thanks to a contribution from @AJamesPhillips, this is now fixed.
- The submodule export for
./access/universal
was broken.
-
The builder returned by
buildThing()
is now stateful. This means you can now do something like this:const bookmarkBuilder = buildThing() .addUrl( "http://www.w3.org/1999/02/22-rdf-syntax-ns#type", "http://www.w3.org/2002/01/bookmark#Bookmark", ) .addUrl("http://www.w3.org/2002/01/bookmark#recalls", form.url); if (typeof form.title !== "undefined") { // In earlier versions, this would be discarded: bookmarkBuilder.addStringNoLocale( "http://purl.org/dc/terms/title", form.title, ); } const bookmark = bookmarkBuilder.build();
- Access Control Policies will no longer support adding a
vcard:Group
to a Rule. Therefore, the low-level ACPs APIs as well as the Universal Access APIs no longer support defining access for avcard:Group
. To define access for multiple agents at the same time, use the mechanism-specific APIs.
- In some cases where the Universal Access APIs would previously bail out, they can now correctly read and change access (at the cost of potentially making more HTTP requests). It will now also work on instances of Inrupt's Enterprise Solid Server not located on inrupt.com, and can now also return the Pod Owner's access on inrupt.com. It will still be unable to report access settings that the current user is not allowed to see.
- We now offer support for the
Date
data type andTime
data type. This includes allset
,get
,add
andremove
methods to modify the Time or Date of a Thing.Time
is a custom data type following the format:
type Time = {
hour: number;
minute: number;
second: number;
timezoneHourOffset?: number;
timezoneMinuteOffset?: number;
};
The added methods are: setDate
, setTime
, getDate
, getDateAll
,
getTime
, getTimeAll
, addDate
, addTime
, removeDate
, removeTime
.
- An update to one of our transitive dependencies (
@rdfjs/data-model
) caused the functions to get data from a Thing (getInteger
,getUrl
, etc.) to break when used in Node.
- To ease interoperability with generic RDF libraries, it is now possibile to
export SolidDatasets into RDF/JS Datasets using
toRdfJsDataset
, and to import existing RDF/JS Dataset for storing on a Solid Pod usingfromRdfJsDataset
. - A new function
buildThing()
makes it easier to set multiple properties on a Thing in one go. So instead of:
let newThing = createThing();
newThing = addUrl(newThing, rdf.type, schema.Person);
newThing = addStringNoLocale(newThing, schema.givenName, "Vincent");
you can now avoid having to repeat newThing
:
const newThing = buildThing()
.addUrl(rdf.type, schema.Person)
.addStringNoLocale(schema.givenName, "Vincent")
.build();
- Since version 1.8.0, TypeScript would no longer warn you if you omitted the
second argument to
asUrl
in cases where it's required, thereby risking runtime errors. In most of these cases, TypeScript should now warn you again.
- The Universal access API's would sometimes attempt to create Access Policies and Rules with invalid URLs, which could be rejected by some Solid servers.
getUrl
now returns local URLs (e.g. #my-thing)getThing
now returns empty Things if they were added, rather thannull
.- The internal structure of SolidDatasets has been reworked. This shouldn't affect you if you relied on just our public API's, but if you were manipulating the data directly, you might need to update to use our public API's. If something's not covered that you need, please file an issue.
getSolidDataset
now returns atomic objects, making it easier to integrate with other tools in the JavaScript ecosystem, easier to debug, and easier to serialise.
- With Node.js version 10 reaching end-of-life on 2021-04-30, @inrupt/solid-client no longer actively supports it. It will not stop working right away, but it will no longer be actively tested and no special effort will be made to keep it from breaking.
- Node.js version 16 is now supported.
- The function
getLinkedResourceUrlAll
that gives you all Resources linked to a given Resource, indexed by their relation to the given Resource. - The function
getEffectiveAccess
, which tells you what access the current user has and, if supported by the server, what access unauthenticated users have to the given Resource.
- While the API documentation mentioned an
isThingLocal
function, it could not actually be imported from@inrupt/solid-client
.
- Saving a dataset to an IRI with a hash fragment (e.g. the WebID) is processed as an update, and not anymore as an overwrite.
- An update in one of our dependencies caused writes to a Pod to fail. This dependency has now been pinned to an older, working version while we investigate further. For more info, see #957.
- A number of new
acp/*
modules are now available that support working directly with Access Control Policies on Pod servers that implement this experimental proposal.
@inrupt/solid-client/access/universal
: an early preview of a set of APIs to manage Access which are agnostic to the Access Control mechanism actually implemented (from the user's point of view). Currently, these modules support the two known access controls for Solid, i.e. Web Access Control and Access Control Policies.
- Saving a SolidDataset with a Thing obtained from a different SolidDataset would fail if that Thing contained an RDF Blank Node.
- Saving back a SolidDataset you just fetched used to result in a "412: Conflict" error.
setGroupDefaultAccess
: A function to set a Group's access modes for all the child Resources of a Container, in the case this Container is controlled using WAC.setGroupResourceAccess
: A function to set a Group's access modes for a given Resource, in the case this Resource is controlled using WAC.
- If you know the content type of a file to upload via
overwriteFile
orsaveFileInContainer
, you can now manually set it using thecontentType
property in theiroptions
parameters. getContainedResourceUrlAll
: a function that returns the URLs for each resource contained in the given Container.- FetchError now contains the server response (
error.response
).
- Files sent to a Pod via
overwriteFile
orsaveFileInContainer
without a known content type were rejected by Inrupt's Enterprise Solid Server with a 400 Bad Request, as the Solid specification says it should do. To avoid this, solid-client now sets the content type toapplication/octet-stream
by default if no content type is known for the given file.
- It is now possible to import solid-client as an ES module in Node.
- A number of error messages have been improved that should make it easier for you to identify what went wrong. If you encounter more unhelpful error messages, please let us know.
- While the documentation mentioned
hasAcl()
, solid-client did not actually export that function. - Dates in between the years 0 and 100 AD were not parsed properly.
- When a function that makes an HTTP request, such as
getSolidDataset
, receives an error response from the server, the error's status code and status text are now exposed via the.statusCode
and.statusText
properties, respectively, on the thrown (/returned in the rejected Promise) Error object. - Additionally, to help you mock the above errors in your unit tests, we now export
mockFetchError()
. Pass it the URL the fake fetch targeted, and optionally the status code that caused the error.
- Our property-based tests discovered a new edge case in which reading a Datetime from the Pod used to fail. That edge case is now handled properly.
- Using solid-client with TypeScript would result in the following error:
error TS2305: Module '"../constants"' has no exported member 'acp'.
This is now fixed, and we are working on preventing such errors in the future.
The big v1! There are no major changes in this release, but from now on, when we intend to change our publicly-documented non-experimental API's, we will bump up the major version to help you plan the impact of the upgrade.
- solid-client will no longer attempt to automatically load solid-auth-client, because it comes with
security risks. It is recommended to use
solid-client-authn-browser
instead. It will remain possible to pass a
fetch
function generated by solid-auth-client to the data fetching functions in solid-client.
- The compiled code of solid-client was not sent to the correct location, causing imports to fail. This bug was introduced in version 0.6.2.
This release contains no public changes.
- When writing non-RDF data, the request headers were incorrectly set.
- All
get*WithAcl()
functions would always fetch both the Resource's own ACL and its fallback ACL, causing issues when the Resource is the Pod's root, but not at the root of the domain, resulting in an attempt to find a fallback ACL for a Resource outside of the Pod. These functions will now only attempt to fetch the Fallback ACL if the Resource's own ACL is not available. Hence, only at most one of the two will be available at any time.
deleteSolidDataset
anddeleteContainer
: two functions that allow you to delete a SolidDataset and a Container from the user's Pod, respectively.hasServerResourceInfo
: a function that determines whether server-provided information about the Resource is present, such as which server-managed Resources are linked to it.getPodOwner
andisPodOwner
allow you to check who owns the Pod that contains a given Resource, if supported by the Pod server and exposed to the current user.
- The type definition of
asUrl
caused the compiler to complain when passing it a Thing of which the final URL was either known or not known yet, when using TypeScript.
- All previously deprecated functions have been removed (their replacements are still available).
- Previously, if no data with the given URL could be found,
getThing
would return a new, empty Thing. From now on, it will returnnull
in those situations.
createAclFromFallbackAcl
did not correctly initialise the new ACL: rules that applied to the applicable Resource's children before the new ACL was created (i.e. defined in the fallback ACL) no longer applied after saving the new one. This is now fixed.
- The experimental function
fetchResourceInfoWithAcl
has been deprecated. It is replaced by the otherwise identical (but still experimental)getResourceInfoWithAcl
.
getResourceInfo
: Function fetching metadata for a resource, without fetching the resource itself. This enables having lightwheight interaction with a Pod before fetching a large file.- When fetching data from or storing data to a Pod results in an error, those error messages now contain more information about what data was being sent, and where it was sent to.
- When creating a new Container on Node Solid Server using
createContainerAt
, no error would be thrown when the Container already exists. Now, as with other Solid servers, an error will be thrown if the Container you are trying to create already exists. - The second, optional parameter to functions like
getSolidDataset
, which allows you to pass e.g. your ownfetch
function, was not included in our type definitions. This prevented editors from autocompleting them, and could cause compilation errors for developers using TypeScript.
thingAsMarkdown()
,solidDatasetAsMarkdown()
andchangeLogAsMarkdown
: functions that take a Thing and SolidDataset (with local changes), respectively, and returns a string representation of it that can assist in debugging issues.
hasResourceInfo
: a function that can verify whether its parameter (e.g. a file or a SolidDataset) was fetched from somewhere, or was initialised in-memory.createContainerAt
andcreateContainerInContainer
: two functions that can help you create an empty Container at a given location or in another Container on the Pod, respectively.isThing
: a function that can verify whether its parameter is a Thing.mockSolidDatasetFrom
,mockContainerFrom
,mockFileFrom
,mockThingFrom
,addMockResourceAclTo
andaddMockFallbackAclTo
: functions that allow you to mock the solid-client data structures in your unit tests.getFileWithAcl
: likegetSolidDatasetWithAcl
, this function lets you fetch a file along with its ACLs, if available.- The legacy predicate
acl:defaultForNew
is now supported by our library. If you interact with a server where it is used to stipulate default access,@inrupt/solid-client
will behave as expected.
getSourceUrl
used to throw an error when called on a Resource that was not fetched from somewhere (and hence had no source URL). It now returnsnull
in that case.- Giving more rights to an Agent or Group could lead to privilege escalation for an app identified
by an
acl:origin
predicate in the ACL. - While we allow reading data of different types, they are stored as plain strings. While multiple
serialisations of data are often possible, we only supported one per data type. What this means
is that, whereas we would correctly return
true
for a boolean stored as"1"
, we would not do so for"true"
, even though both are valid serialisations of the valuetrue
according to the XML Schema Datatypes specification: https://www.w3.org/TR/xmlschema-2. solid-client now recognises all valid serialisations of all supported data types as defined by that specification.
First release! What's possible with this first release:
- Fetch data from Solid Pods or other public sources that publish Turtle data.
- Store data back to Solid Pods.
- Read data from datasets.
- Manipulate data in datasets.
- Inspect a user's, group's and public permissions w.r.t. a given Resource or child Resources of a Container. (Experimental.)
- Retrieve, delete and/or write any file (including non-RDF) from/to a Pod. (Experimental.)