- Ketting now requires Node 18.
- #476: When
cache: no-store
is specified onfetch()
functions, Ketting will now no longer store responses with aContent-Location
in its internal cache. - #477: When storing responses with
Content-Location
, bodies are now cloned before storing so callees can still read the date. - Testing Node 20.
- Added HAL 'name' property to links.
- Updates for changes in Typescript strictness.
- Ketting requires Node 16 now.
- No longer using
node-fetch
, asfetch()
is natively supported on Node 18. If you are using Ketting with Node 16, you should installnode-fetch
or run node with the--experimental-fetch
option. - Upgraded OAuth2 dependency to @badgateway/oauth2-client.
- Submitting actions with missing required fields will now throw an exception.
- Actions that have pre-filled values will auto submit those values unless they are explicitly overridden.
- #459: Now uses the correct spelling of 'placeholder' in HAL forms (@dayre).
- Export the
FetchMiddleware
type. - #444: Allow multiple query parameters to be set with the same key when specifying template variables. (@qmachard)
- Upgrade to Typescript 5
- Updating dependencies.
- Typescript 4.8 support!
- #401: The mechanism that de-duplicates identical requests is now a bit
smarter, and will not de-duplicate requests that are significantly different
such as a different
Accept
header. (@hugothomas @reda-alaoui) - #450:
value
field for some HAL inputs were ignored (color, checkbox, radio).
- Added support for
minLength
andmaxLength
attributes on textarea fields in HAL Forms. (@dayre).
Idential to the last beta. Contains the following features that were introduced in the previous betas:
- #433: Fixed race condition when processing nested
_embedded
resources and emitingupdate
events. The order at which they happen is now consistent. When theupdate
event happens, the entire cache should be up to date. - #328:
Resource.go()
andClient.go()
can now take aLink
object as the argument.
- Fixed a bug that was introduced with #433.
- #433: Fixed race condition when processing nested
_embedded
resources and emitingupdate
events. The order at which they happen is now consistent. When theupdate
event happens, the entire cache should be up to date. - #328:
Resource.go()
andClient.go()
can now take aLink
object as the argument.
- #426: Setting up cache dependencies through
inv-by
links is now possible via HAL_links
and in embedded resources, as well as links from all the other formats. - #425: Fewer warnings related to 'Max listeners exceeded'. The default of 10 is too low for typical Ketting applications.
- #416: Cache-dependencies setup with
inv-by
links are now respected when manually clearing resource caches. - #414: Don't attempt to parse the response if it had a
204
status, even if there was aContent-Type
header. - #408: Emit a warning when an
_embedded
HAL item is missing a goodself
link.
- #395: Relative URIs in embedded HAL documents are now resolved using the 'self' link in the embedded document, instead of the parent. Although not explicitly said in the HAL standards, I feel this is the right behavior. Most users will not see a difference, but if you relied on the old behavior this could cause some subtle BC breaks.
- #392: The
action()
function on State classes would only return the default action (@reda-alaoui). - Changed how Cache classes are exported, as an experiment to see if IDE docs are more complete.
- Support for the
inv-by
Link relationship type from the Linked Cache Invalidation draft. This link lets a resource tell the client that it's cache should expire when the linked resource's cache also expires. - The 'prompt' field in HAL Forms for properties with 'options' set was ignored.
- No longer testing Node 10 and Node 15. Added Node 16.
- Actions are now retained when caching. Before this, action information was dropped which meant that any actions in embedded resources were not accessible. (@hugothomas)
- New major version! See Github for a list of changes.
Title
header is now defined as a HTTP Entity Header.
label
andvalue
were parsed in reverse.
- Added renderAs 'checkbox' to multi-select fields in actions.
- Export
OptionDataSource
.
- Support for HAL Forms version
2021-02-20
, which adds the 'options' property. - Kettings now has support for 'dropdown' fields, allowing users to provide lists of possible options in 3 different ways: 1. An inline list 2. An external HTTP resource (JSON body or CSV body) 3. Provided as links from a hypermedia source. Only 1 and 2 are supported by HAL Forms, 3 is just an internal feature until there is a format that has first-class support for this.
- A bit of a rewrite of 'fields' again. Only a single type is exported, and all the types are cleaned up.
- Support for Siren 'title' on fields. This was an oversight.
- Remove support for
Prefer-Push
. Browsers are basically dropping HTTP/2 Push, and not enough work is done to make this very interesting. More background. - Revert 'unifiying URLs' PR, we're back to using
url.resolve
in node.
- Note: this release has a number of BC breaks, which will only affect you if you wrote custom format parsers. See the wiki for more details.
- #326: State objects now have
follow()
andfollowAll()
methods. - #322: Add
type
,status
,detail
,instance
properties toProblem
class, for better support ofapplication/problem+json
. (@sazzer). - #327: If a response is received with a
Content-Location
header, the response will now immediately get stored in the cache. - Support for
draft-dalal-deprecation-header
. Ketting will now emit warnings if aDeprecation
header is detected, and will also provide information from theSunset
header and include the uri of thedeprecation
link relation. - Support for the latest HAL-Forms features, including
target
,step
,min
,max
,type
,minLength
,maxLength
,placeholder
,cols
,rows
. - Support multiple HAL Forms, as per the latest spec updates. Before only a 'default' form was supported.
- Add
textarea
form field type. - #324: Only use
{cache: 'no-cache'}
with.refresh()
, not.get()
. - Fixed a subtle URL resolving bug in browsers. (Node was not affected).
- Updated
fetch-mw-oauth2
, which has a few new features: * Fixed a race condition where two 401's in quick succession could result in two OAuth2 refresh requests, ultimately causing 1 to fail. * Preemptively refresh if we know when the access token will expire.
- #302: Templated links without template data don't work.
- Add a
getCache()
function to Resource, which allows a user to get the latest Resource State in a synchronous manner. - #292: Parse Siren's 'value' property in action fields.
fetch-mw-oauth2
dependency had a bug related to refreshing tokens. This release ships with a version without that bug.
- Update the
fetch-mw-oauth2
dependency, which adds anonAuthError
event.
state.links.delete()
can now take ahref
argument to delete a specific link from its list.- Improvements in error messaging.
- Upgrade to Webpack 5
- Large changes in the actions/form system. This should still be considered experimental and could cause some minor BC breaks.
- Actions are now effectively a serialization of a HTML form, and it's now
possible to introspect information such as the
target
,method
,contentType
, etc. - Some refactoring in the
State
objects, simplifiying these significantly.
- State objects now have an
actions()
method that return all defined actions.
- #241: Add
application/prs.hal-forms+json
to Accept header and treat as HAL (@reda-alaoui). - #260:
action()
could not be successfully called on a HAL action. (@reda-alaoui). - Add
action()
function toState
interface.
- #248: Parse JSON objects that have an array at the top-level.
- #257:
ETag
andLast-Modified
are now treated as 'Content headers', which means they will get returned fromgetContentHeaders()
.
- Quick re-release. Some files were left in the
dist/
directory that were not cleaned up.
- Support
draft-nottingham-link-hint
on Links. - Added:
client.fetcher.advertiseKetting
. Setting this to false will cause Ketting to not set theUser-Agent
header. Resource.patch()
will now return aState
object if the server responded with200 OK
and a body.
- #229: Embedded resources were not cached. (@madsmadsen)
- #230: Respect
headers
property in options ofrefresh()
function. (@madsmadsen) - Lots of Ketting 6 doc updates.
- JSDocs everywhere gotten a fresh proof read.
- Switched from tslint to eslint.
- Feature complete!
isState()
type guard is exported.
- The Links object now has a default 'context', making it easier to add relative links.
- Links now has an easier to use API for setting or adding new links.
- Links now has a
.delete()
method to delete byrel
.
- Added 'actions', allowing users to automatically submit actions and/or Forms for supported formats.
- Action support is added for
text/html
andapplication/vnd.siren+json
- Supported content-types for actions are
application/json
andapplication/x-www-form-urlencoded
. State
objects now have a reference toClient
.resolve()
function is now a package export, providing a cross-platform function for resolving urls.Resource
has now aupdateCache
function for local state changes without submitting to the server.refresh()
now emits anupdate
event.
- Fixing bugs related to
patch()
,post()
in the browser build.
Resources
implement EventEmitter, and can emitstale
,update
anddelete
events.- The 'body' property on State is now 'data'
- #141: Added
head()
function and ability to follow links just throughHEAD
methods via theLink
header. - Added a
NeverCache
andShortCache
if automatically storing everyState
object until invalidation is not desired. - When calling
put()
with a newState
object, that object will now be placed in cache. - When refreshing,
fetch()
is now given the 'reload' cache setting, so thatrefresh()
is a true Refresh, even with a browser cache. - #130: Support relative bookmark URIs when using Ketting in a browser.
- Siren was not correctly parsed.
- Add
.clone()
method to allState
object.
State
is now exported.- #184: Added a new
postFollow()
function that takes over the role ofpost()
.post()
is now intended for RPC-like operations and form submissions.
- Re-release. The build contained a few older files that weren't meant to be packaged.
- Big BC-breaking rewrite. Changes are numerous, but the important ones are listed here.
Resource.get()
now returns aState
object instead of just a response body. This object has methods to make it easier to manipulate and get information about the response, including links. It's also a stable, non-async object.Ketting
class is now calledClient
. It's still exposed asKetting
as well for BC purposes.Client.getResource()
has been removed. UseClient.go()
instead.- A HTTP Fetch middleware system has been added, for easier manipulation of requests and responses. Middlewares can be added for every request, or for specific origins (domains).
- All authentication settings have been removed, and reimplemented as fetch middlewares. They take roughly the same options, but the setup has changed.
Resource.get()
,Resource.put()
, etc. can now all take custom headers and other options to manipulate the request.- In the past you could just send a body with
Resource.post()
,.put()
, .patch()
. Now this body must be a wrapped in an object with at least a.body
property. This is an annoying BC break but will allow for more flexibility that was previous impossible. - Proper support for 'binary' resources.
- Hal Links will now be reserialized on
put()
. Resource.link
,Resource.links
andResource.hasLink
has been deprecated, but not removed.Link
objects are now a simple typescript type, and no longer implemented as a class.FollowerOne
is nowFollowPromiseOne
andFollowerMany
is nowFollowPromiseMany
.- All things called
Representor
has been removed, and rewritten with a completely new API. AHAL representor
is now aHalState
. - #175: Nested embedded items are now also placed in the cache.
- Use the
title=
attribute from the HTTP Link header, if it exists.
- Added 'finally()' to custom follower promises.
- All representors are now exported in the
representor
namespace.
- Correct return type on followAll, so it may be chained with preFetch. This was only an issue when doing 'multiple hops'.
- #173: De-duplicate HAL links if they appear in _embedded and _links.
- Support for the Collection+json format.
- Added a
preferTransclude()
method on the Follower objects. This automatically adds aPrefer: tranclude="rel"
header.
- Update all dependencies.
- This version is the exact same as the previous alpha.
- Added
hasLink
on Resources and Representations.
- Fixed a bug in
getOptions()
- Added a
preferPush()
method to 'Follower' objects, allowing you to automatically sendPrefer-Push
headers when following links. - Moved all functionality related to the 'Repreprentor' in a utility class,
making both the
Ketting
andResource
classes simpler. - Simplified
Resource.refresh()
, making it easier to read and do less work. - When calling
.post()
, the function will only return a new resource if the HTTP response code was201
. - If the HTTP response code to a
post()
call was205
, it will now return the current resource. - Removed the logic for automatically adding
Prefer-Push
headers. This was unreliable, and usually did the wrong thing. The new system is 100% opt-in and developer-driven. - Added
Ketting.getOptions()
to return a list of options that were passed to Ketting. The options will be enhanced with OAuth2 refresh and access tokens as they become available, meaning that it can be used to place in LocalStorage to remember sessions. This feature is experimental and incomplete. It might change even in minor versions.
- This version is identical to the last, but fixes an issue on npmjs.com. Updating is not needed.
- It's now possible to tell Ketting to prefetch every resource when following
links via
Resource.follow('foo').preFetch()
. Link
andLinkNotFound
are now both exported.- Documentation overhaul.
- Slight tweak to the webpack build, so that other typescript + webpack projects can use the webpack build and use the minified files.
- Now supports the 'invalidates' link rel. When specified in a HTTP response, Ketting will automatically clear the cache of any related resources. See draft-nottingham-linked-cache-inv-04.
- Support for the Siren format.
- Rewrite of the 'representation' system, which is responsible for supporting all the different media types. This results in a few small BC breaks.
- NEW:
follow()
andfollowAll()
now throwLinkNotFound
instead of the genericError
when a link could not be found. - NEW: Resources now have a
link(rel: string)
function, which returns a a singleLink
object. - BC BREAK:
Ketting.getRepresentor()
is nowKetting.createRepresentation()
and is responsible for constructing the object instead of just returning a constructor. - BC Break:
body
,links
andembedded
onRepresentor
objects are all gone and replaced withgetBody()
,getLinks()
andgetEmbedded()
. - BUG: Hal is now more lenient with broken responses.
- NEW: Compatible with Typescript's
strictNullChecks
setting. Overall stronger typing all around. - NEW: Hal responses from the HAL representor are now properly typed.
- CHANGE: Link chaining system has been rewritten, opening the door to new features that weren't possible before.
- This version is identical to the last, but fixes an issue on npmjs.com. Updating is not needed.
- The internal resource cache will now evict items for any non-safe HTTP method.
- Broke Typescript exports again
- Fix Typescript defintion files so Ketting may be imported correctly.
- #129: Using the package in non-typescript node.js now works with a simple
const Ketting = require('ketting')
. - #129: Fixed the browser distribution. the
Ketting
constructor is registered globally again.
- The old format for OAuth2 setup is now no longer supported.
- It's now possible to specify per-domain authentication using wildcards. This allows you to set up specific authentication credentials for specific domains. This might be useful in case you talk to multiple API's with a single client.
- If Ketting anticipates that a user might want to fetch multiple resources in
sequence (a follow chain), it will now add
Prefer-Push
header and aPrefer: transclude
header. Both are experimental internet drafts to suggest to a server to do a HTTP/2 push or embed a child resource respecitvely. This feature is experimental and might change as these drafts change.
- A mistake was made when releasing version 3. A branched was not merged in entirely, which caused some of the new OAuth2 features to be partially missing. This has now been corrected.
- Updated dependencies
- Switched OAuth2 implementation from
client-oauth2
tofetch-mw-oauth2
. This adds support forauthorization_code
auth, removes 11 dependencies and reduces the minified Ketting build from 69KB to 28KB. - OAuth2 options now have a new format. The old format is still supported, but will be removed from a future version.
- The
baseHref
propertyname was renamed toContext
on theLink
type. The new name matches the name from RFC8288. This is a small BC break.
- #120: The system that de-duplicates identical requests will cache failures forever. This is now fixed. Highly recommended update.
- Basic JSON:API support. Currently only links appearing in the top-level document are supported.
- #113: Support for Typescript environments that don't have
esModuleInterop
set to true. - Added a 'go' function for easily getting resources based on relative uris.
- If a link appears in both
_embedded
and_links
, they will be de-duplicated. HAL technically requires links to appear in both places, so scanning_embedded
should not be needed. However, most implementations will not add links_links
if they were already_embedded
. This change caters both usages.
- The
Resource
class is now a generic typescript type. This allows a user of the library to define specific 'types of resources' and leverage static typing forGET
andPUT
requests. - A few documentation updates.
- Better handling of
Content-Types
. When following HAL links that have atype
parameter, the type is rememebered and used inAccept
andContent-Type
headers, forGET
,PUT
andPOST
requests. - If no
type
was provided, it will use the lastContent-Type
header fromGET
response. - If that
GET
request never happened, it uses the first 'default'Content-Type
from client.contentTypes, and enumerates all mime-types from that list forAccept
headers. - No longer incorrectly sends
text/plain
Content-Types. - Optimization: If multiple calls are made to ask for a Resource's current
representation, all these calls are coalesced into one. The big benefit is
that there are no longer multiple parallel
GET
requests. - Webpack browser build is set to 'production' mode.
- Fixed: After refreshing an OAuth2 token, the new access token wasn't used.
- Refreshing OAuth2 tokens without having a refresh_token.
client_credentials
in particular shouldn't return arefresh_token
, so for these cases, new access tokens are acquired using a newclient_credentials
request.
- Support for OAuth2
client_credentials
grant.
- No longer ships with
cross-fetch
andwhatwg-fetch
. To use this library in a browser, you must run this in a browser that supportsfetch
or provide your own polyfill. - Updated dependencies
- Fixed bug: HAL title values weren't parsed.
- Exporting 'Resource' for TS purposes.
- Updated dependencies
- Fixed a typescript definition problem.
- Same as last build.
- #71: Total conversion to Typescript.
- BC break: Minified files are now in the
browser/
directory, not thedist/
directory. - #78: Webpack build had a broken version of
querystring
, which causedLink:
header parsing to fail in browsers. - #80:
resource.fetch()
would throw an exception with some combinations of arguments. - #90:
get()
andrefresh()
will now throw an Error when a server did not include a content-type. - #89: Refactored OAuth utility to be a bit more clear.
- #83: Support for
resource.patch()
. The implementation is pretty basic. Let us know how you would like to use it!
- #70: Moved all source from
lib/
tosrc/
. This is prepping for typescript support. - #73: Mocha tests can now be ran in a browser.
- #76: Fixed a browser bug: Headers is not a constructor.
- #66: Support for Accept header weighing with the q= parameter.
- #68: Updated all dependencies to their latest version.
- #63: It was not possible to expand templated links with variables after more than one chained hop. (@mhum).
- #62: It was not possible to override headers such as
Content-Type
when callingResource.fetch()
, if these were also set in thefetchInit
defaults. (@mhum).
- #60: Chaining more than 2
follow
statements did not work.
- #19: Support for OAuth2 access and refresh tokens. When used, the library can
automatically refresh the access token if the previous one expired. It can
also supports the
client_credentials
OAuth2 grant (@mhum).
- #52: Now using the new URL object in browsers for resolving relative urls, and falling back to a DOM based url resolving mechanism if it's not available. This causes the browser distribution to drop another 10KB to 46KB.
- Moved a bunch of utility objects into a
util/
directory, so it's more clear what the important API's are. - #55: Fixed another problem related to the fetchInit function in firefox.
- Including the sourcemap file in the NPM distribution.
- #53: Regression related to the new 'fetchInit' option.
- Now generating source maps.
- #50: Allow Fetch settings to be passed to the constructor of Ketting, so that
settings such as
credentials: include
may be passed.
- #49: Removed support for expanding CURIEs in HAL. This was in conflict with the HAL standard. The canonical relation type is the prefix in the REL, not the expanded CURIE uri.
- Lots of documentation updates.
- Including web distribution in NPM package.
- This library is now called Ketting. It used to be called Restl. Ketting is the dutch word for chain.
- Automatically expanding Curies in the HAL
_link
object.
- #15: Browser support via webpack!
- #45: Removed Bluebird dependency.
- #16: Parsing the HTTP
Link
header (RFC5988). - #30: Added support for automatically parsing
application/problem+json
error responses and throwing better exceptions. (RFC7807). - #47: Link object now uses an object as its only constructor argument.
- #41: Support for parsing HTML5. The library can now extract
link
anda
elements withrel
attributes. - Removed the
accept
option. This should now be controlled with thecontentTypes
property. - #40: Removed support for the Requests library. This library now only used the Fetch API, to make it compatible with browsers in the future.
- #39: Making it easier to fire off custom HTTP requests on a resource using
the Fetch API. You can now just provide the
init
argument without providing a url.
- #38: Add HTTP response to HTTP-related exceptions.
- #37: Support for templated uris.
- #33: Support for OAuth2 Bearer token.
- #31: Support for setting a standard
Content-Type
HTTP header.
- #28: Support for Basic Authentication
- #27: Fixed exception messages, they missed the HTTP status code.
- #17: Now using the Fetch API instead of the requests library. The requests library is kept around for BC purposes, but this will eventually be removed.
- #25: the resourceCache was accidentally shared between Client instances.
- #11: Added test framework.
- #11: Added
follow()
function on Client object for an easy shortcut.
- #10: Returning the response body from the
refresh()
function, similar toGET
but cache-defeating.
- #7: Strip
_embedded
and_links
fromRepresentation.body
. They are already available throughRepresentation.embedded
andRepresentation.links
. - Added a cache for resources in the Client object, which ensures that if you request the same resource twice, you'll end up with the same object.
- #6: Automatically parse
_embedded
and treat items in this object as real resources. - Fixed a bug in
post()
. - Allowing custom headers to be set, and allowing default headers to be overridden.
- Automatically resolve all urls from
links()
.
- Bugfixes.
- Linting with eslint.
- Now using Bluebird for promises, so we can extend them.
- #2: Custom requests are now possible on
Resource
objects. - #3: Promises returned from
follow()
now have afollow()
function themselves, making it extremely easy to hop from link to link. - Added a
post()
method for making new resources. This function returns aResource
object again if the response contained aLocation
header. - #4: Things in the
_embedded
property are now also treated as links and can be followed. - The
links()
method on Resource now have arel
argument for easy filtering. - Added a
followAll()
function for getting collections.
PUT
request.DELETE
request.
- First version!
- Parses HAL
_links
. - Follows links.
GET
requests.refresh()
function.