mirror of
https://github.com/directus/directus.git
synced 2026-01-23 08:58:22 -05:00
828 lines
15 KiB
Markdown
828 lines
15 KiB
Markdown
# JavaScript SDK
|
|
|
|
> The JS SDK provides an intuitive interface for the Directus API from within a JavaScript-powered project (browsers and
|
|
> node.js). The default implementation uses [Axios](https://npmjs.com/axios) for transport and `localStorage` for
|
|
> storing state.
|
|
|
|
[[toc]]
|
|
|
|
## Installation
|
|
|
|
```bash
|
|
npm install @directus/sdk
|
|
```
|
|
|
|
## Usage
|
|
|
|
```js
|
|
import { Directus } from '@directus/sdk';
|
|
|
|
const directus = new Directus('https://api.example.com/');
|
|
```
|
|
|
|
**NOTE** _All_ methods return promises. Make sure to await methods, for example:
|
|
|
|
```js
|
|
import { Directus } from '@directus/sdk';
|
|
|
|
const directus = new Directus('https://api.example.com/');
|
|
|
|
// Wait for login to be done...
|
|
await directus.auth.login({
|
|
email: 'admin@example.com',
|
|
password: 'password',
|
|
});
|
|
|
|
// ... before fetching items
|
|
const articles = await directus.items('articles').readMany();
|
|
|
|
console.log({
|
|
items: articles.data,
|
|
total: articles.meta.total_count,
|
|
});
|
|
```
|
|
|
|
## Global
|
|
|
|
### Initialize
|
|
|
|
```js
|
|
import { Directus } from '@directus/sdk';
|
|
|
|
const directus = new Directus('https://api.example.com/');
|
|
```
|
|
|
|
#### `url`
|
|
|
|
The constructor accepts the URL as the first parameter.
|
|
|
|
#### `options.auth`
|
|
|
|
The authentication implementation. See [Auth](#auth) for more information.
|
|
|
|
Defaults to an instance `Auth`.
|
|
|
|
#### `options.storage`
|
|
|
|
The storage implementation. See [Storage](#storage) for more information.
|
|
|
|
Defaults to an instance of `MemoryStorage` when in node.js, and `LocalStorage` when in browsers.
|
|
|
|
#### `options.transport`
|
|
|
|
The transport implementation. See [Transport](#transport) for more information.
|
|
|
|
Defaults to an instance of `AxiosTransport`.
|
|
|
|
### Full Example
|
|
|
|
```js
|
|
const url = 'http://api.example.com/';
|
|
|
|
// Storage adapter where refresh tokens are stored in JSON mode.
|
|
const storage = new MemoryStorage();
|
|
|
|
// Transport used to communicate with the server.
|
|
const transport = new AxiosTransport(url, storage);
|
|
|
|
// Auth is how authentication is handled, stored, and refreshed.
|
|
const auth = new Auth(transport, storage, {
|
|
mode: 'json', // or cookie, depends on your use case
|
|
});
|
|
|
|
const directus = new Directus(url, {
|
|
auth,
|
|
storage,
|
|
transport,
|
|
});
|
|
```
|
|
|
|
### Get / Set API URL
|
|
|
|
```js
|
|
// Get the API base URL
|
|
console.log(directus.url); // => https://api.example.com/
|
|
|
|
// Set the API base URL
|
|
directus.transport.url = 'https://api2.example.com';
|
|
```
|
|
|
|
### Access to transport/Axios
|
|
|
|
You can tap into the transport through `directus.transport`. If you are using the (default) `AxiosTransport`, you can
|
|
access axios through `directus.transport.axios`.
|
|
|
|
## Items
|
|
|
|
You can get an instance of the item handler by providing the collection (and type, in the case of TypeScript) to the
|
|
`items` function. The following examples will use the `Article` type.
|
|
|
|
> JavaScript
|
|
|
|
```js
|
|
// import { Directus, ID } from '@directus/sdk';
|
|
const { Directus } = require('@directus/sdk');
|
|
|
|
const directus = new Directus('https://api.example.com');
|
|
|
|
const articles = directus.items('articles');
|
|
```
|
|
|
|
> TypeScript
|
|
|
|
```ts
|
|
import { Directus, ID } from '@directus/sdk';
|
|
|
|
// Map your collection structure based on its fields.
|
|
type Article = {
|
|
id: ID;
|
|
title: string;
|
|
body: string;
|
|
published: boolean;
|
|
};
|
|
|
|
// Map your collections to its respective types. The SDK will
|
|
// infer its types based on usage later.
|
|
type MyBlog = {
|
|
// [collection_name]: typescript_type
|
|
articles: Article;
|
|
|
|
// You can also extend Directus collection. The naming has
|
|
// to match a Directus system collection and it will be merged
|
|
// into the system spec.
|
|
directus_users: {
|
|
bio: string;
|
|
};
|
|
};
|
|
|
|
// Let the SDK know about your collection types.
|
|
const directus = new Directus<MyBlog>('https://directus.myblog.com');
|
|
|
|
// typeof(article) is a partial "Article"
|
|
const article = await directus.items('articles').readOne(10);
|
|
|
|
// Error TS2322: "hello" is not assignable to type "boolean".
|
|
// post.published = 'hello';
|
|
```
|
|
|
|
### Create Single Item
|
|
|
|
```js
|
|
await articles.createOne({
|
|
title: 'My New Article',
|
|
});
|
|
```
|
|
|
|
### Create Multiple Items
|
|
|
|
```js
|
|
await articles.createMany([
|
|
{
|
|
title: 'My First Article',
|
|
},
|
|
{
|
|
title: 'My Second Article',
|
|
},
|
|
]);
|
|
```
|
|
|
|
### Read All
|
|
|
|
```js
|
|
await articles.readMany();
|
|
```
|
|
|
|
### Read By Query
|
|
|
|
```js
|
|
await articles.readMany({
|
|
search: 'Directus',
|
|
filter: {
|
|
date_published: {
|
|
_gte: '$NOW',
|
|
},
|
|
},
|
|
});
|
|
```
|
|
|
|
### Read By Primary Key(s)
|
|
|
|
```js
|
|
await articles.readOne(15);
|
|
```
|
|
|
|
Supports optional query:
|
|
|
|
```js
|
|
// One
|
|
await articles.readOne(15, { fields: ['title'] });
|
|
```
|
|
|
|
Supports optional query:
|
|
|
|
```js
|
|
await articles.updateOne(15, { title: 'An Updated title' }, { fields: ['title'] });
|
|
|
|
await articles.updateMany(
|
|
[
|
|
/*...*/
|
|
],
|
|
{ fields: ['title'] }
|
|
);
|
|
```
|
|
|
|
### Update Multiple Items
|
|
|
|
```js
|
|
await articles.updateMany([
|
|
{
|
|
id: 15,
|
|
title: 'Article 15',
|
|
},
|
|
{
|
|
id: 42,
|
|
title: 'Article 42',
|
|
},
|
|
]);
|
|
```
|
|
|
|
Supports optional query:
|
|
|
|
```js
|
|
await articles.updateMany(
|
|
[
|
|
{
|
|
id: 15,
|
|
title: 'Article 15',
|
|
},
|
|
{
|
|
id: 42,
|
|
title: 'Article 42',
|
|
},
|
|
],
|
|
{ fields: ['title'] }
|
|
);
|
|
```
|
|
|
|
### Delete
|
|
|
|
```js
|
|
// One
|
|
await articles.deleteOne(15);
|
|
|
|
// Multiple
|
|
await articles.deleteMany([15, 42]);
|
|
```
|
|
|
|
## Activity
|
|
|
|
### Read All Activity
|
|
|
|
```js
|
|
await directus.activity.readMany();
|
|
```
|
|
|
|
### Read Activity By Query
|
|
|
|
```js
|
|
await directus.activity.readMany({
|
|
filter: {
|
|
action: {
|
|
_eq: 'create',
|
|
},
|
|
},
|
|
});
|
|
```
|
|
|
|
### Read Activity By Primary Key(s)
|
|
|
|
```js
|
|
await directus.activity.readOne(15);
|
|
```
|
|
|
|
Supports optional query:
|
|
|
|
```js
|
|
await directus.activity.readOne(15, { fields: ['action'] });
|
|
```
|
|
|
|
### Create a Comment
|
|
|
|
```js
|
|
await directus.activity.comments.create({
|
|
collection: 'articles',
|
|
item: 15,
|
|
comment: 'Hello, world!',
|
|
});
|
|
```
|
|
|
|
### Update a comment
|
|
|
|
```js
|
|
await directus.activity.comments.update(31, {
|
|
comment: 'Howdy, world!',
|
|
});
|
|
```
|
|
|
|
Note: The passed key is the primary key of the comment
|
|
|
|
### Delete a comment
|
|
|
|
```js
|
|
await directus.activity.comments.delete(31);
|
|
```
|
|
|
|
Note: The passed key is the primary key of the comment
|
|
|
|
## Auth
|
|
|
|
### Configuration
|
|
|
|
Directus will accept custom implementations of the `IAuth` interface. The default implementation `Auth` can be imported
|
|
from `@directus/sdk`. The default implementation will require you to pass the transport and storage implementations. All
|
|
options are optional.
|
|
|
|
```js
|
|
import { Auth } from '@directus/sdk';
|
|
|
|
// ...
|
|
|
|
const sdk = new Directus('url', {
|
|
auth: new Auth(transport, storage, options);
|
|
// ...
|
|
});
|
|
```
|
|
|
|
#### transport
|
|
|
|
The transport responsible for communicating with Directus backend.
|
|
|
|
Defaults to an instance of `AxiosTransport` when not creating `Auth` youself.
|
|
|
|
#### storage
|
|
|
|
The storage responsible for storing authentication and sdk state.
|
|
|
|
When not creating `Auth` youself, defaults to `MemoryStorage` in node.js, and `LocalStorage` in browsers.
|
|
|
|
#### options.mode
|
|
|
|
Accepts `cookie` or `json`.
|
|
|
|
When in `cookie` mode, the API will set the refresh token in an `httpOnly` secure cookie that can't be accessed from
|
|
client side JavaScript. This is the most secure way to connect to the API from a public front-end website.
|
|
|
|
When you can't rely on cookies, or need more control over handling the storage of the cookie (like in node.js), use
|
|
`json` mode. This will return the refresh token in the "normal" payload. The storage of these tokens are handled by the
|
|
`storage` implementation.
|
|
|
|
Defaults to `cookie` in browsers, `json` in node.js.
|
|
|
|
### Full example
|
|
|
|
```js
|
|
import { Auth, AxiosTransport, Directus, MemoryStorage } from '@directus/sdk';
|
|
|
|
const url = 'http://directus';
|
|
|
|
const storage = new MemoryStorage();
|
|
const transport = new AxiosTransport(url, storage);
|
|
const auth = new Auth(transport, storage, {
|
|
mode: 'json',
|
|
});
|
|
|
|
const directus = new Directus(url, {
|
|
auth,
|
|
storage,
|
|
transport,
|
|
});
|
|
|
|
await directus.auth.login({
|
|
email: 'admin@example.com',
|
|
password: 'password',
|
|
});
|
|
```
|
|
|
|
### Get current token
|
|
|
|
```ts
|
|
const token = directus.auth.token;
|
|
```
|
|
|
|
### Login
|
|
|
|
#### With credentials
|
|
|
|
```js
|
|
await directus.auth.login({
|
|
email: 'admin@example.com',
|
|
password: 'd1r3ctu5',
|
|
});
|
|
```
|
|
|
|
#### With static tokens
|
|
|
|
```js
|
|
await directus.auth.static('static_token');
|
|
```
|
|
|
|
#### Refresh auth token
|
|
|
|
You can set authentication to auto-refresh the token once it's close to expire.
|
|
|
|
```js
|
|
await directus.auth.login(
|
|
{
|
|
email: 'admin@example.com',
|
|
password: 'd1r3ctu5',
|
|
},
|
|
{
|
|
refresh: {
|
|
auto: true,
|
|
},
|
|
}
|
|
);
|
|
```
|
|
|
|
You can also set how much time before the expiration you want to auto-refresh the token.
|
|
|
|
```js
|
|
await directus.auth.login(
|
|
{
|
|
email: 'admin@example.com',
|
|
password: 'd1r3ctu5',
|
|
},
|
|
{
|
|
refresh: {
|
|
auto: true,
|
|
time: 30000, // refesh the token 30 secs before the expiration
|
|
},
|
|
}
|
|
);
|
|
```
|
|
|
|
### Refresh Auth Token
|
|
|
|
You can manually refresh the authentication token.
|
|
|
|
```js
|
|
await directus.auth.refresh();
|
|
```
|
|
|
|
An optional parameter will accept auto-refresh information.
|
|
|
|
```js
|
|
await directus.auth.refresh({
|
|
auto: true,
|
|
time: 30000, // refesh the token 30 secs before the expiration
|
|
});
|
|
```
|
|
|
|
### Logout
|
|
|
|
```js
|
|
await directus.auth.logout();
|
|
```
|
|
|
|
### Request a Password Reset
|
|
|
|
```js
|
|
await directus.auth.password.request('admin@example.com');
|
|
```
|
|
|
|
### Reset a Password
|
|
|
|
```js
|
|
await directus.auth.password.reset('abc.def.ghi', 'n3w-p455w0rd');
|
|
```
|
|
|
|
Note: The token passed in the first parameter is sent in an email to the user when using `request()`
|
|
|
|
## Transport
|
|
|
|
The transport object abstracts how you communicate with Directus. Transports can be customized to use different HTTP
|
|
libraries for example.
|
|
|
|
### Interface
|
|
|
|
```ts
|
|
// Simplified version, `import { ITransport } from '@directus/sdk';`
|
|
interface ITransport {
|
|
url;
|
|
get(path);
|
|
head(path);
|
|
options(path);
|
|
delete(path, data = undefined);
|
|
post(path, data);
|
|
put(path, data);
|
|
patch(path, data);
|
|
}
|
|
```
|
|
|
|
### AxiosTransport
|
|
|
|
The default transport used in both browser and node deployments.
|
|
|
|
#### Options
|
|
|
|
AxiosTransport requires a base URL and a storage implementation to work.
|
|
|
|
```ts
|
|
const transport = new AxiosTransport('http://example.com', new MemoryStorage());
|
|
await transport.get('/server/info');
|
|
```
|
|
|
|
## Storage
|
|
|
|
The storage is used to load and save SDK data.
|
|
|
|
### LocalStorage
|
|
|
|
The storage used in environments where Local Storage is supported.
|
|
|
|
#### Options
|
|
|
|
The `LocalStorage` implementation accepts a _transparent_ prefix. Use this when you need multiple SDK instances with
|
|
independent authentication for example.
|
|
|
|
### MemoryStorage
|
|
|
|
The storage used when SDK data is ephemeral. For example: only during the lifecycle of the process.
|
|
|
|
#### Options
|
|
|
|
The `MemoryStorage` implementation accepts a _transparent_ prefix so you can have multiple instances of the SDK without
|
|
having clashing keys.
|
|
|
|
## Collections
|
|
|
|
```js
|
|
directus.collections;
|
|
```
|
|
|
|
Same methods as `directus.items("directus_collections")`.
|
|
|
|
## Fields
|
|
|
|
```js
|
|
directus.fields;
|
|
```
|
|
|
|
Same methods as `directus.items("directus_fields")`.
|
|
|
|
## Files
|
|
|
|
```js
|
|
directus.files;
|
|
```
|
|
|
|
Same methods as `directus.items("directus_files")`.
|
|
|
|
## Folders
|
|
|
|
```js
|
|
directus.folders;
|
|
```
|
|
|
|
Same methods as `directus.items("directus_folders")`.
|
|
|
|
## Permissions
|
|
|
|
```js
|
|
directus.permissions;
|
|
```
|
|
|
|
Same methods as `directus.items("directus_permissions")`.
|
|
|
|
## Presets
|
|
|
|
```js
|
|
directus.presets;
|
|
```
|
|
|
|
Same methods as `directus.items("directus_presets")`.
|
|
|
|
## Relations
|
|
|
|
```js
|
|
directus.relations;
|
|
```
|
|
|
|
Same methods as `directus.items("directus_relations")`.
|
|
|
|
## Revisions
|
|
|
|
```js
|
|
directus.revisions;
|
|
```
|
|
|
|
Same methods as `directus.items("directus_revisions")`.
|
|
|
|
## Roles
|
|
|
|
```js
|
|
directus.roles;
|
|
```
|
|
|
|
Same methods as `directus.items("directus_roles")`.
|
|
|
|
## Settings
|
|
|
|
```js
|
|
directus.settings;
|
|
```
|
|
|
|
Same methods as `directus.items("directus_settings")`.
|
|
|
|
## Server
|
|
|
|
### Ping the Server
|
|
|
|
```js
|
|
await directus.server.ping();
|
|
```
|
|
|
|
### Get Server/Project Info
|
|
|
|
```js
|
|
await directus.server.info();
|
|
```
|
|
|
|
## Users
|
|
|
|
```js
|
|
directus.users;
|
|
```
|
|
|
|
Same methods as `directus.items("directus_users")`, and:
|
|
|
|
### Invite a New User
|
|
|
|
```js
|
|
await directus.users.invites.send('admin@example.com', 'fe38136e-52f7-4622-8498-112b8a32a1e2');
|
|
```
|
|
|
|
The second parameter is the role of the user
|
|
|
|
### Accept a User Invite
|
|
|
|
```js
|
|
await directus.users.invites.accept('<accept-token>', 'n3w-p455w0rd');
|
|
```
|
|
|
|
The provided token is sent to the user's email
|
|
|
|
### Enable Two-Factor Authentication
|
|
|
|
```js
|
|
await directus.users.tfa.enable('my-password');
|
|
```
|
|
|
|
### Disable Two-Factor Authentication
|
|
|
|
```js
|
|
await directus.users.tfa.disable('691402');
|
|
```
|
|
|
|
### Get the Current User
|
|
|
|
```js
|
|
await directus.users.me.read();
|
|
```
|
|
|
|
Supports optional query:
|
|
|
|
```js
|
|
await directus.users.me.read({
|
|
fields: ['last_access'],
|
|
});
|
|
```
|
|
|
|
### Update the Current Users
|
|
|
|
```js
|
|
await directus.users.me.update({ first_name: 'Admin' });
|
|
```
|
|
|
|
Supports optional query:
|
|
|
|
```js
|
|
await directus.users.me.update({ first_name: 'Admin' }, { fields: ['last_access'] });
|
|
```
|
|
|
|
## Utils
|
|
|
|
### Get a Random String
|
|
|
|
```js
|
|
await directus.utils.random.string();
|
|
```
|
|
|
|
Supports an optional `length` (defaults to 32):
|
|
|
|
```js
|
|
await directus.utils.random.string(50);
|
|
```
|
|
|
|
### Generate a Hash for a Given Value
|
|
|
|
```js
|
|
await directus.utils.hash.generate('My String');
|
|
```
|
|
|
|
### Verify if a Hash is Valid
|
|
|
|
```js
|
|
await directus.utils.hash.verify('My String', '$argon2i$v=19$m=4096,t=3,p=1$A5uogJh');
|
|
```
|
|
|
|
### Sort Items in a Collection
|
|
|
|
```js
|
|
await directus.utils.sort('articles', 15, 42);
|
|
```
|
|
|
|
This will move item `15` to the position of item `42`, and move everything in between one "slot" up.
|
|
|
|
### Revert to a Previous Revision
|
|
|
|
```js
|
|
await directus.utils.revert(451);
|
|
```
|
|
|
|
Note: The key passed is the primary key of the revision you'd like to apply.
|
|
|
|
---
|
|
|
|
## TypeScript
|
|
|
|
If you are using TypeScript, the JS-SDK requires TypeScript 3.8 or newer. TypeScript will also improve the development
|
|
experience by providing relevant information when manipulating your data. For example, `directus.items` knows about your
|
|
collection types if you feed the SDK with enough information in the construction of the SDK instance. This allows for a
|
|
more detailed IDE suggestions for return types, sorting, and filtering.
|
|
|
|
```ts
|
|
type BlogPost = {
|
|
id: ID;
|
|
title: string;
|
|
};
|
|
|
|
type BlogSettings = {
|
|
display_promotions: boolean;
|
|
};
|
|
|
|
type MyCollections = {
|
|
posts: BlogPost;
|
|
settings: BlogSettings;
|
|
};
|
|
|
|
// This is how you feed custom type information to Directus.
|
|
const directus = new Directus<MyCollections>('http://url');
|
|
|
|
// ...
|
|
|
|
const post = await directus.items('posts').readOne(1);
|
|
// typeof(post) is a partial BlogPost object
|
|
|
|
const settings = await posts.singleton('settings').read();
|
|
// typeof(settings) is a partial BlogSettings object
|
|
```
|
|
|
|
You can also extend the Directus system type information by providing type information for system collections as well.
|
|
|
|
```ts
|
|
import { Directus } from '@directus/sdk';
|
|
|
|
// Custom fields added to Directus user collection.
|
|
type UserType = {
|
|
level: number;
|
|
experience: number;
|
|
};
|
|
|
|
type CustomTypes = {
|
|
/*
|
|
This type will be merged with Directus user type.
|
|
It's important that the naming matches a directus
|
|
collection name exactly. Typos won't get caught here
|
|
since SDK will assume it's a custom user collection.
|
|
*/
|
|
directus_users: UserType;
|
|
};
|
|
|
|
const directus = new Directus<CustomTypes>('https://api.example.com');
|
|
|
|
await directus.auth.login({
|
|
email: 'admin@example.com',
|
|
password: 'password',
|
|
});
|
|
|
|
const me = await directus.users.me.read();
|
|
// typeof me = partial DirectusUser & UserType;
|
|
|
|
// OK
|
|
me.level = 42;
|
|
|
|
// Error TS2322: Type "string" is not assignable to type "number".
|
|
me.experience = 'high';
|
|
```
|