Skip to content

Cozy Client API

Classes

Association

Associations are used by components to access related store documents that are linked in a document. They are also responsible for building the QueryDefinition that is used by the client to automatically fetch relationship data.

Hydrated documents used by components come with Association instances.

HasMany

Related documents are stored in the relationships attribute of the object, following the JSON API spec.

Responsible for

  • Creating relationships
  • Removing relationships
HasManyInPlace

Used when related documents are stored directly under the attribute with only the ids.

HasManyTriggersHasMany

Association used for konnectors to retrieve all their related triggers.

CozyClient

Responsible for

  • Creating observable queries
  • Hydration
  • Creating plan for saving documents
  • Associations
QueryDefinition

Chainable API to create query definitions to retrieve documents from a Cozy. QueryDefinitions are sent to links.

Schema

Stores information on a particular doctype.

  • Attribute validation
  • Relationship access
const schema = new Schema({
  todos: {
    attributes: {
      label: {
        unique: true
      }
    },
    relationships: {
      author: 'has-one-in-place'
    }
  }
}, cozyStackClient)

Constants

triggerStates

Trigger states come from /jobs/triggers

fetchPolicies

Use those fetch policies with <Query /> to limit the number of re-fetch.

Functions

createClientInteractive()

Creates a client with interactive authentication.

  • Will start an OAuth flow and open an authentication page
  • Starts a local server to listen for the oauth callback
  • Resolves with the client after user authentication
withClient(Component)function

HOC to provide client from context as prop

queryConnect(querySpecs)function

HOC creator to connect component to several queries in a declarative manner

sanitizeCategories()

Filters unauthorized categories. Defaults to ['others'] if no suitable category.

sanitize(manifest)Manifest

Normalize app manifest, retrocompatibility for old manifests

currentResult()HydratedQueryState

Returns the query from the store with hydrated documents.

fetchMore()

Generates and executes a query that is offsetted by the number of documents we have in the store.

cancelable(promise)AugmentedPromise

Wraps a promise so that it can be canceled

Rejects with canceled: true as soon as cancel is called

Association

Associations are used by components to access related store documents that are linked in a document. They are also responsible for building the QueryDefinition that is used by the client to automatically fetch relationship data.

Hydrated documents used by components come with Association instances.

Kind: global class

new Association(target, name, doctype, options)

Example: The schema defines an author relationship :

const BOOK_SCHEMA = {
  relationships: {
     author: 'has-one'
  }
}

Hydrated books will have the author association instance under the author key. Accessing hydratedBook.author.data gives you the author from the store, for example :

{
  "name": "St-Exupery",
  "firstName": "Antoine",
  "_id": "antoine"
}

It is the responsibility of the relationship to decide how the relationship data is stored. For example, here since we use the default has-one relationship, the relationship data is stored in the relationships attribute of the original document (in our case here, our book would be

{
  "title": "Le petit prince",
  "relationships": {
    "author": {
      "data": {
        "doctype": "io.cozy.authors",
        "_id": "antoine"
      }
    }
  }
}

In the case of an “in-place” relationship, the relationship data is stored directly under the attribute named by the relationship (in our case author). Our book would be

{
    "title": "Le petit prince",
    "author": "antoine"
}

Each different type of Association may change:

  • get raw: how the relationship data is stored (either as per the JSON API spec or in a custom way)
  • get data: how the store documents are then fetched from the store to be added to the hydrated document (.data method). View components will access hydratedDoc[relationshipName].data.
  • get query: how to build the query to fetch related documents
Param Type Description
target object Original object containing raw data
name string Attribute under which the association is stored
doctype string Doctype of the documents managed by the association
options.dispatch function Store’s dispatch, comes from the client
options string

association.target : object

The original document declaring the relationship

Kind: instance property of Association

association.name : string

The name of the relationship.

Kind: instance property of Association
Example

'author'

association.doctype : string

Doctype of the relationship

Kind: instance property of Association
Example

'io.cozy.authors'

association.get : function

Returns the document from the store

Kind: instance property of Association

association.save : function

Saves the relationship in store.

Kind: instance property of Association

association.dispatch : function

Dispatch an action on the store.

Kind: instance property of Association

association.raw

Returns the raw relationship data as stored in the original document

For a document with relationships stored as JSON API spec:

const book = {
  title: 'Moby Dick',
  relationships: {
    author: {
      data: {
        doctype: 'io.cozy.authors',
        id: 'herman'
      }
    }
  }
 }

Raw value will be

{
  "doctype": "io.cozy.authors",
  "id": "herman"
}

Derived Associations need to implement this method.

Kind: instance property of Association

association.data

Returns the document(s) from the store

For document with relationships stored as JSON API spec :

const book = {
  title: 'Moby Dick',
  relationships: {
    author: {
      data: {
        doctype: 'io.cozy.authors',
        id: 'herman'
      }
    }
  }
 }

data will be

{
  "_id": "herman"
  "_type": "io.cozy.authors",
  "firstName": "herman",
  "name": "Melville"
}

Derived Associations need to implement this method.

Kind: instance property of Association

association.query(queryDefinition)

Performs a query to retrieve relationship documents.

Kind: instance method of Association

Param Type
queryDefinition QueryDefinition

association.mutate()

Performs a mutation on the relationship.

Kind: instance method of Association

Association.query() ⇒ QueryDefinition

Derived Associations need to implement this method.

Kind: static method of Association

HasMany

Related documents are stored in the relationships attribute of the object, following the JSON API spec.

Responsible for

  • Creating relationships
  • Removing relationships

Kind: global class

new HasMany()

const schema = {
  todos: {
     doctype: 'io.cozy.todos',
     relationships: {
       tasks: {
         doctype: 'io.cozy.tasks',
         type: 'has-many'
       }
     }
   }
}

const todo = {
  label: "Protect people's privacy",
  relationships: {
    tasks: {
      data: [
        {_id: 1, _type: 'io.cozy.tasks'},
        {_id: 2, _type: 'io.cozy.tasks'}
      ]
    }
  }
}

hasMany.addById()

Add a referenced document by id. You need to call save() in order to synchronize your document with the store.

Kind: instance method of HasMany
Todo

  • [ ] We shouldn’t create the array of relationship manually since it’ll not be present in the store as well. We certainly should use something like updateRelationship

HasManyInPlace

Used when related documents are stored directly under the attribute with only the ids.

Kind: global class

new HasManyInPlace()

An example document representing a TODO. See as the related tasks are represented via ids.

const todo = {
  label: "Protect people's privacy",
  tasks: [1, 2]
}

Here is the Schema that would represent this kind of document. Components receiving todos via Querys would have an instance of HasManyInPlace as their tasks attribute.

const schema = {
  todos: {
     doctype: 'io.cozy.todos',
     relationships: {
       tasks: {
         doctype: 'io.cozy.tasks',
         type: 'has-many-in-place'
       }
     }
   }
}

const todo = {
  label: "Get rich",
  tasks: [1, 2]
}

HasManyTriggers ⇐ HasMany

Association used for konnectors to retrieve all their related triggers.

Kind: global class
Extends: HasMany

hasManyTriggers.addById()

Add a referenced document by id. You need to call save() in order to synchronize your document with the store.

Kind: instance method of HasManyTriggers
Todo

  • [ ] We shouldn’t create the array of relationship manually since it’ll not be present in the store as well. We certainly should use something like updateRelationship

HasManyTriggers.query()

In this association the query is special, we need to fetch all the triggers having for the ‘konnector’ worker, and then filter them based on their message.konnector attribute

Kind: static method of HasManyTriggers

CozyClient

Responsible for

  • Creating observable queries
  • Hydration
  • Creating plan for saving documents
  • Associations

Kind: global class

new CozyClient(options)

Param Type Description
options object
options.link Link Backward compatibility
options.links Array.Link List of links
options.schema object Schema description for each doctypes
options.appMetadata object Metadata about the application that will be used in ensureCozyMetadata Cozy-Client will automatically call this.login() if provided with a token and an uri

cozyClient.registerPlugin()

A plugin is a class whose constructor receives the client as first argument. The main mean of interaction with the client should be with events like “login”/”logout”.

The plugin system is meant to encourage separation of concerns, modularity and testability : instead of registering events at module level, please create a plugin that subscribes to events.

Plugin instances are stored internally in the plugins attribute of the client and can be accessed via this mean. A plugin class must have the attribute pluginName that will be use as the key in the plugins object.

Two plugins with the same pluginName cannot co-exist.

Kind: instance method of CozyClient
Example

class AlertPlugin {
  constructor(client, options) {
    this.client = client
    this.options = options
    this.handleLogin = this.handleLogin.bind(this)
    this.handleLogout = this.handleLogout.bind(this)
    this.client.on("login", this.handleLogin)
    this.client.on("logout", this.handleLogout)
  }

  handleLogin() {
    alert(this.options.onLoginAlert)
  }

  handleLogout() {
    alert(this.options.onLogoutAlert)
  }
}

AlertPlugin.pluginName = 'alerts'

client.registerPlugin(AlertPlugin, {
  onLoginAlert: 'client has logged in !',
  onLogoutAlert: 'client has logged out !'
})

// the instance of the plugin is accessible via
client.plugins.alerts

cozyClient.login() ⇒ Promise

Notify the links that they can start and set isLogged to true.

On mobile, where url/token are set after instantiation, use this method to set the token and uri via options.

Emits

  • “beforeLogin” at the beginning, before links have been set up
  • “login” when the client is fully logged in and links have been set up

Kind: instance method of CozyClient
Returns: Promise - - Resolves when all links have been setup and client is fully logged in

Param Type Description
options.token options.token If passed, the token is set on the client
options.uri options.uri If passed, the uri is set on the client

cozyClient.logout() ⇒ Promise

Logs out the client and reset all the links

Emits

  • “beforeLogout” at the beginning, before links have been reset
  • “login” when the client is fully logged out and links have been reset

Kind: instance method of CozyClient
Returns: Promise - - Resolves when all links have been reset and client is fully logged out

cozyClient.collection(doctype) ⇒ DocumentCollection

Forwards to a stack client instance and returns a DocumentCollection instance.

Kind: instance method of CozyClient

Param Type Description
doctype string The collection doctype.

cozyClient.getDocumentSavePlan(document, relationships) ⇒ Array.<Mutation>

Creates a list of mutations to execute to create a document and its relationships.

const baseDoc = { _type: 'io.cozy.todo', label: 'Go hiking' }
// relations can be arrays or single objects
const relationships = {
  attachments: [{ _id: 12345, _type: 'io.cozy.files' }, { _id: 6789, _type: 'io.cozy.files' }],
  bills: { _id: 9999, _type: 'io.cozy.bills' }
}
client.getDocumentSavePlan(baseDoc, relationships)

Kind: instance method of CozyClient
Returns: Array.<Mutation> - One or more mutation to execute

Param Type Description
document object The base document to create
relationships object The list of relationships to add, as a dictionnary. Keys should be relationship names and values the documents to link.

cozyClient.destroy(document) ⇒ Document

Destroys a document. {before,after}:destroy hooks will be fired.

Kind: instance method of CozyClient
Returns: Document - The document that has been deleted

Param Type
document Document

cozyClient.query(queryDefinition) ⇒ QueryResult

Executes a query and returns its results.

Results from the query will be saved internally and can be retrieved via getQueryFromState or directly using <Query />. <Query /> automatically executes its query when mounted if no fetch policy has been indicated.

Kind: instance method of CozyClient

Param Type Description
queryDefinition QueryDefinition
options.as string Names the query so it can be reused (by multiple components for example)

cozyClient.queryAll(queryDefinition, options) ⇒ Array

Will fetch all documents for a queryDefinition, automatically fetching more documents if the total of documents is superior to the pagination limit. Can result in a lot of network requests.

Kind: instance method of CozyClient
Returns: Array - All documents matching the query

Param Type Description
queryDefinition QueryDefinition
options object Options to the query

cozyClient.fetchRelationships()

Fetch relationships for a response (can be several docs). Fills the relationships attribute of each documents.

Can potentially result in several fetch requests. Queries are optimized before being sent (multiple single documents queries can be packed into one multiple document query) for example.

Kind: instance method of CozyClient

cozyClient.hydrateDocuments(doctype, documents) ⇒ Array.<HydratedDocument>

Returns documents with their relationships resolved according to their schema. If related documents are not in the store, they will not be fetched automatically. Instead, the relationships will have null documents.

Kind: instance method of CozyClient

Param Type
doctype string
documents Array.<Document>

cozyClient.hydrateDocument(document, schema) ⇒ HydrateDocument

Resolves relationships on a document.

The original document is kept in the target attribute of the relationship

Kind: instance method of CozyClient

Param Type Description
document Document for which relationships must be resolved
schema Schema for the document doctype

cozyClient.makeNewDocument()

Creates (locally) a new document for the given doctype. This document is hydrated : its relationships are there and working.

Kind: instance method of CozyClient

cozyClient.getAssociation()

Creates an association that is linked to the store.

Kind: instance method of CozyClient

cozyClient.getRelationshipStoreAccessors()

Returns the accessors that are given to the relationships for them to deal with the stores.

Relationships need to have access to the store to ping it when a modification (addById/removeById etc…) has been done. This wakes the store up, which in turn will update the <Query>s and re-render the data.

Kind: instance method of CozyClient

cozyClient.getCollectionFromState(type) ⇒ Array.<Document>

Get a collection of documents from the internal store.

Kind: instance method of CozyClient
Returns: Array.<Document> - Array of documents or null if the collection does not exist.

Param Type Description
type string Doctype of the collection

cozyClient.getDocumentFromState(type, id) ⇒ Document

Get a document from the internal store.

Kind: instance method of CozyClient
Returns: Document - Document or null if the object does not exist.

Param Type Description
type string Doctype of the document
id string Id of the document

cozyClient.getQueryFromState(id) ⇒ QueryState

Get a query from the internal store.

Kind: instance method of CozyClient
Returns: QueryState - - Query state or null if it does not exist.

Param Type Description
id string Id of the query (set via Query.props.as)
options.hydrated boolean Whether documents should be returned already hydrated (default: false)

cozyClient.register(cozyURL) ⇒ object

Performs a complete OAuth flow using a Cordova webview for auth. The register method’s name has been chosen for compat reasons with the Authentication compo.

Kind: instance method of CozyClient
Returns: object - Contains the fetched token and the client information.

Param Type Description
cozyURL string Receives the URL of the cozy instance.

cozyClient.startOAuthFlow(openURLCallback) ⇒ object

Performs a complete OAuth flow, including updating the internal token at the end.

Kind: instance method of CozyClient
Returns: object - Contains the fetched token and the client information. These should be stored and used to restore the client.

Param Type Description
openURLCallback function Receives the URL to present to the user as a parameter, and should return a promise that resolves with the URL the user was redirected to after accepting the permissions.

cozyClient.renewAuthorization() ⇒ object

Renews the token if, for instance, new permissions are required or token has expired.

Kind: instance method of CozyClient
Returns: object - Contains the fetched token and the client information.

cozyClient.setStore(store)

Sets the internal store of the client. Use this when you want to have cozy-client’s internal store colocated with your existing Redux store.

Typically, you would need to do this only once in your application, this is why setStore throws if you do it twice. If you really need to set the store again, use options.force = true.

Kind: instance method of CozyClient

Param Type Description
store ReduxStore A redux store
options.force boolean Will deactivate throwing when client’s store already exists

Example

const client = new CozyClient()
const store = createStore(combineReducers({
  todos: todoReducer,
  cozy: client.reducer()
})
client.setStore(store)

cozyClient.handleRevocationChange()

Sets public attribute and emits event related to revocation

Kind: instance method of CozyClient

cozyClient.handleTokenRefresh()

Emits event when token is refreshed

Kind: instance method of CozyClient

cozyClient.createClient()

If no stack client has been passed in options, creates a default stack client and attaches handlers for revocation and token refresh. If a stackClient has been passed in options, ensure it has handlers for revocation and token refresh.

If oauth options are passed, stackClient is an OAuthStackClient.

Kind: instance method of CozyClient

cozyClient.setData(data)

Directly set the data in the store, without using a query This is useful for cases like Pouch replication, which wants to set some data in the store.

Kind: instance method of CozyClient

Param Type Description
data Object

CozyClient.fromOldClient()

To help with the transition from cozy-client-js to cozy-client, it is possible to instantiate a client with an instance of cozy-client-js.

Kind: static method of CozyClient

CozyClient.fromEnv()

In konnector/service context, CozyClient can be instantiated from environment variables

Kind: static method of CozyClient

CozyClient.registerHook(doctype, name, fn)

Hooks are an observable system for events on documents. There are at the moment only 2 hooks available.

  • before:destroy, called just before a document is destroyed via CozyClient::destroy
  • after:destroy, called after a document is destroyed via CozyClient::destroy

Kind: static method of CozyClient

Param Type Description
doctype string
name string Name of the hook
fn function Callback

Example

CozyClient.registerHook('io.cozy.bank.accounts', 'before:destroy', () => {
  console.log('A io.cozy.bank.accounts is being destroyed')
})

QueryDefinition

Chainable API to create query definitions to retrieve documents from a Cozy. QueryDefinitions are sent to links.

Kind: global class

new QueryDefinition(doctype, id, ids, selector, fields, indexedFields, sort, includes, referenced, limit, skip)

Param Type Description
doctype string The doctype of the doc.
id string The id of the doc.
ids Array The ids of the docs.
selector object The selector to query the docs.
fields Array The fields to return.
indexedFields Array The fields to index.
sort Array The sorting params.
includes string The docs to include.
referenced string The referenced document.
limit number The document’s limit to return.
skip number The number of docs to skip.

queryDefinition.getById(id) ⇒ QueryDefinition

Query a single document on its id.

Kind: instance method of QueryDefinition
Returns: QueryDefinition - The QueryDefinition object.

Param Type Description
id string The document id.

queryDefinition.getByIds(ids) ⇒ QueryDefinition

Query several documents on their ids.

Kind: instance method of QueryDefinition
Returns: QueryDefinition - The QueryDefinition object.

Param Type Description
ids Array The documents ids.

queryDefinition.where(selector) ⇒ QueryDefinition

Query documents with a mango selector. Each field passed in the selector will be indexed, except if the indexField option is used.

Kind: instance method of QueryDefinition
Returns: QueryDefinition - The QueryDefinition object.

Param Type Description
selector object The Mango selector.

queryDefinition.select(fields) ⇒ QueryDefinition

Specify which fields of each object should be returned. If it is omitted, the entire object is returned.

Kind: instance method of QueryDefinition
Returns: QueryDefinition - The QueryDefinition object.

Param Type Description
fields Array The fields to return.

queryDefinition.indexFields(fields) ⇒ QueryDefinition

Specify which fields should be indexed. This prevent the automatic indexing of the mango fields.

Kind: instance method of QueryDefinition
Returns: QueryDefinition - The QueryDefinition object.

Param Type Description
fields Array The fields to index.

queryDefinition.sortBy(sort) ⇒ QueryDefinition

Specify how to sort documents, following the sort syntax

Kind: instance method of QueryDefinition
Returns: QueryDefinition - The QueryDefinition object.

Param Type Description
sort Array The list of field name and direction pairs.

queryDefinition.include(includes) ⇒ QueryDefinition

Includes documents having a relationships with the ones queried. For example, query albums including the photos.

Kind: instance method of QueryDefinition
Returns: QueryDefinition - The QueryDefinition object.

Param Type Description
includes Array The documents to include.

queryDefinition.limitBy(limit) ⇒ QueryDefinition

Maximum number of documents returned, useful for pagination. Default is 100.

Kind: instance method of QueryDefinition
Returns: QueryDefinition - The QueryDefinition object.

Param Type Description
limit number The document’s limit.

queryDefinition.offset(skip) ⇒ QueryDefinition

Skip the first ‘n’ documents, where ‘n’ is the value specified.

Beware, this performs badly on view’s index. Prefer cursor-based pagination in such situation.

Kind: instance method of QueryDefinition
Returns: QueryDefinition - The QueryDefinition object.

Param Type Description
skip number The number of documents to skip.

queryDefinition.offsetCursor(cursor) ⇒ QueryDefinition

Use cursor-based pagination. Warning: this is only useful for views. The cursor is a [startkey, startkey_docid] array, where startkey is the view’s key, e.g. [“io.cozy.photos.albums”, “album-id”] and startkey_docid is the id of the starting document of the query, e.g. “file-id”. Use the last docid of each query as startkey_docid to paginate or leave blank for the first query.

Kind: instance method of QueryDefinition
Returns: QueryDefinition - The QueryDefinition object.

Param Type Description
cursor Array The cursor for pagination.

queryDefinition.referencedBy(document) ⇒ QueryDefinition

Use the file reference system

Kind: instance method of QueryDefinition
Returns: QueryDefinition - The QueryDefinition object.

Param Type Description
document object The reference document

Schema

Stores information on a particular doctype.

  • Attribute validation
  • Relationship access
const schema = new Schema({
  todos: {
    attributes: {
      label: {
        unique: true
      }
    },
    relationships: {
      author: 'has-one-in-place'
    }
  }
}, cozyStackClient)

Kind: global class

schema.getDoctypeSchema()

Returns the schema for a doctype

Creates an empty schema implicitly if it does not exist

Kind: instance method of Schema

schema.getRelationship()

Returns the relationship for a given doctype/name

Kind: instance method of Schema

schema.validate()

Validates a document considering the descriptions in schema.attributes.

Kind: instance method of Schema

triggerStates

Trigger states come from /jobs/triggers

Kind: global constant

triggerStates.getLastExecution()

Returns when the trigger was last executed. Need a trigger

Kind: static method of triggerStates

triggerStates.isErrored()

Returns whether last job failed

Kind: static method of triggerStates

fetchPolicies

Use those fetch policies with <Query /> to limit the number of re-fetch.

Kind: global constant
Example

import { fetchPolicies } from 'cozy-client'
const olderThan30s = fetchPolicies.olderThan(30 * 1000)
<Query fetchPolicy={olderThan30s} />

fetchPolicies.olderThan(delay) ⇒ function

Returns a fetchPolicy that will only re-fetch queries that are older than <delay> ms.

Kind: static method of fetchPolicies
Returns: function - Fetch policy to be used with <Query />

Param Type Description
delay number Milliseconds since the query has been fetched

fetchPolicies.noFetch()

Fetch policy that deactivates any fetching.

Kind: static method of fetchPolicies

createClientInteractive()

Creates a client with interactive authentication.

  • Will start an OAuth flow and open an authentication page
  • Starts a local server to listen for the oauth callback
  • Resolves with the client after user authentication

Kind: global function
Params: Object clientOptions Same as CozyClient::constructor.
Example

import { createClientInteractive } from 'cozy-client/dist/cli'
await createClientInteractive({
  uri: 'http://cozy.tools:8080',
  scope: ['io.cozy.bills'],
  oauth: {
    softwareID: 'my-cli-application-using-bills'
  }
})

withClient(Component) ⇒ function

HOC to provide client from context as prop

Kind: global function
Returns: function - - Component that will receive client as prop

Param Type Description
Component Component wrapped component

queryConnect(querySpecs) ⇒ function

HOC creator to connect component to several queries in a declarative manner

Kind: global function
Returns: function - - HOC to apply to a component

Param Type Description
querySpecs object Definition of the queries

sanitizeCategories()

Filters unauthorized categories. Defaults to [‘others’] if no suitable category.

Kind: global function

sanitize(manifest) ⇒ Manifest

Normalize app manifest, retrocompatibility for old manifests

Kind: global function

Param Type
manifest Manifest

currentResult() ⇒ HydratedQueryState

Returns the query from the store with hydrated documents.

Kind: global function

fetchMore()

Generates and executes a query that is offsetted by the number of documents we have in the store.

Kind: global function

cancelable(promise) ⇒ AugmentedPromise

Wraps a promise so that it can be canceled

Rejects with canceled: true as soon as cancel is called

Kind: global function
Returns: AugmentedPromise - - Promise with .cancel method

Param Type
promise Promise