* Setup build chain
* Initial structure
* Typing, exports, fix build
* Reorganize
* prutsen met output types
* Thursday fun times
* failed experiments in feature composition
* got feature flags on the client
* using interfaces instead of literals
* messed with decorators
* split up decorators
* added fetch and ws types
* reintroduced the global.d.ts we'll figure that out later
* reworked composables
* some changes
* experimenting with commands
* got the read item command working again with types
* trying authentication
* basic gql implementation
* Super basic websocket implementation
* renamed websocket composable and removed obsolete code
* Typing relational fields
Co-authored-by: Rijk van Zanten <rijkvanzanten@me.com>
* fixed recursive type
* SDK revamp revamp (#18916)
* Split up files
* Simplify some more (too much?)
* Oh boy we figured out object extending
* OK JK now we're there
* OK getting somewhere real now
* Start structuring type helpers
* Types werken zowaar!
* Remove unneeded "T"'s for readability
* Added support for array relational types
* split up query nesting logic
* make relational fields optional to support multiple relations
* improved readability
* updated REST
* Move URL to top level
* Remove T
* recursively join fields in params
* cleaning up
* updated graphql implementation
* removing old unused code
---------
Co-authored-by: Brainslug <tim@brainslug.nl>
* Reduce global reuse of rest
* Start messing with output types
* Return it from the rest command
* first level schema output filtering
* It works!! but will need some docs for context
* Added some comments
* removed export keyword from types that do not need to be exported
* cleaned up debug script
* graphql update
* Added dom for WebSocket and Fetch typings
* initial readme setup
* moved some types
* removed accidental commit
* Refactor `useDirectus` and improve token handling (#18966)
* Add comment and reduce code of useDirectus
* Add fabian-hiller to contributors.yml
* Change token handling of useDirectus client
---------
Co-authored-by: Brainslug <br41nslug@users.noreply.github.com>
* Change ClientConfig type back to interface (#18968)
* initial realtime feature
* started on some ws commands and implemented message receiving callback
* disabled rest config for now
* setup auth extension boilerplate
* Added some websocket examples to the readme
* docs: add getting started guide
* docs: add link to previous sdk
* docs: updates
* implemented readItem
* updated readItems
* Added delete commands
* docs: updates to snippets and phrasing
* updated lockfile
* Update dictionary
* docs: removed repeated typescript snippet
* Enrich package.json for SDK
* docs: update snippet
* Fix casing of readme
* added create items commands
* fixed read items output
* removed obsolete types
* added update commands
* updated tsup
* removed unused dependencies
* implemented basic memory storage fallback
* implemented the login function for auth
* implemented refresh and logout auth functions
* docs: update guide
* updated auth refresh logic
* oops, have to actually store the expires at value
* fixed authentication timeout
* added autoRefresh config option
* updated readme
* updated getting started
* docs: updates to guide
* added beta version nr
* removed debug scripts
* added docblocks to the composables
* Added some docblocks
* Added BETA warning to readme
* Added extra type extends object checks
* added a bunch of index files
* updated tsup build entrypoints and exports
* updated import paths
* updated code examples
* docs: removed unnecessary phrases
* Unignore SDK changesets
* Revert "docs: removed unnecessary phrases"
This reverts commit 3559ade873.
* docs: removed unnecessary phrases
* Make sure we export all available functions
* Tweak exports
* Add TypeDoc for new (and old) SDK
* Update docs/guides/sdk/getting-started.md
* Re-add beta version flag in package.json
* Format readme
* Tweaks
* Spellchecker
* v10.4.0
* Add link to TypeDoc of new SDK
* updated query types
* trying to expand the query types
* extending the Query options
* add all exports to the root
* fixed incorrect field mapping
* Abstracted more of the request logic for more flexibility
* partial error handling, global fetch settings and fetch response options
* reworked the requests for better options control and started on better error handling
* type fix
* Run formatter & linter
* Spell fixes
* added onRequest handler
* updated global request hooks
* expanded ItemType to accept singletons
* updated output types for singletons
* fixed fields type generation
* removed rest globaloptions in favor of onRequest
* started singleton command
* different commands for singletons
* ran prettier
* updated readme
* stateless helpers for tomorrow
* support m2a in field types
* added m2a fields parsing and attempt at output typing
* made the base client stateless
* making sure things are exported as needed
* added minimal core table schema for files and users
* added update singleton command
* Added core user read commands
* merged related commands into the same file
* Added create users commands
* Added user update commands
* added user delete commands
* updated query handling
* ran prettier and bumped version
* ran prettier
* disabled global error handling for now
* fixed output formatting for delete commands
* fixed onResponse handling
* fixed item types for create and update
* added missing partial item for create
* ran prettier
* updated readme
* added missing export
* Publish beta version
* Added a bunch of core collection types
* updated users commands
* added more complex core types
* double checked nullable core fields
* fixed core collection merging with custom properties
* added authentication commands
* ran prettier and fixed line endings
* Added all core read commands
* Added all core create commands
* Added all core delete commands
* Added all core update commands
* ran prettier
* renamed `useDirectus` to `createDirectus` and `.use` to `.with` to prevent naming confusion with reacthooks or express middleware.
* ran prettier
* added more misc core commands
* added schema endpoints
* added server api commands
* ran prettier
* added most utility endpoints
* finished utility endpoints
* checking the command typing and jsdoc
* fixed those pesky relational output types
* ran prettier
* removed obsolete type
* initial aggregation typing
* improved aggregation and grouping typing
* ran prettier
* checked exports
* Beta 4
* fixed the m2a fields regression
* added basic client test
* do query parsing at the latest stage
* extra type comments
* reverted accidental commit and ran prettier
* Adjust tsconfig to updated @directus/tsconfig package
* updated websocket event handling
* fixed capitalization
* removed obsolete queryToParams usage
* implemented websocket reconnecting and some non-happy path fixes
* persist subscription across reconnecting
* updated readme
* ran prettier
* 11.0.0-beta.5
* using plurar for uploadFiles ad removed "D" from updateFiles
* fix incorrect paths
* created new util types file
* extracted output types
* fixed input typing issue (for items)
* extracted functions to its own file
* fixed path for presets
* ran prettier
* Applied typing fix to all commands
* fixed naming error `updatedItems` -> `updateItems`
* fixed type error
* Failing types gracefully if no schema is provided
* beta.6
* Clean-up tsup config
- Use documented way to define config
- Doesn't need to be ts file: not type checked, intellisense available
in vscode anyway
- remove default & deprecated options
* added other user commands
* added other share commands
* satisfy prettier
* added string array types to webhook core schema
* fixed plain string request output
* keep nullability for relational fields
* Update documentation guides to use new SDK (#19131)
Co-authored-by: Rijk van Zanten <rijkvanzanten@me.com>
Co-authored-by: Kevin Lewis <kvn@lws.io>
Co-authored-by: Pascal Jufer <pascal-jufer@bluewin.ch>
Co-authored-by: Brainslug <tim@brainslug.nl>
* Fix error messages for core collections
* updated dictionary
* updated partial item input for fields
* Ready, set, go!
---------
Co-authored-by: rijkvanzanten <rijkvanzanten@me.com>
Co-authored-by: Fabian Hiller <35291865+fabian-hiller@users.noreply.github.com>
Co-authored-by: Esther Agbaje <folasadeagbaje@gmail.com>
Co-authored-by: Pascal Jufer <pascal-jufer@bluewin.ch>
Co-authored-by: Esther Agbaje <53586167+estheragbaje@users.noreply.github.com>
Co-authored-by: Kevin Lewis <kvn@lws.io>
24 KiB
description, readTime
| description | readTime |
|---|---|
| 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. | 14 min read |
JavaScript SDK (pre v11)
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 for transport and
localStoragefor storing state. Advanced customizations are available.
::: danger This SDK is no longer supported!
Version 11 introduced a complete rewrite of our SDK and the version referenced on this page is no longer supported either in terms of code or help in our community spaces. This page is purely for reference. New SDK docs can be found here.
:::
Installation
npm install @directus/sdk@10
Basic Usage
This is the starting point to use the JS SDK. After you've created the Directus instance, you can start invoking
methods from it to access your project and data.
import { Directus } from '@directus/sdk';
const directus = new Directus('http://directus.example.com');
You can always access data available to the public role.
async function publicData() {
// GET DATA
// We don't need to authenticate if the public role has access to some_public_collection.
const publicData = await directus.items('some_public_collection').readByQuery({ sort: ['id'] });
console.log(publicData.data);
}
Basic Authentication
To access anything that is not available to the public role, you must be authenticated.
async function start() {
// AUTHENTICATION
let authenticated = false;
// Try to authenticate with token if exists
await directus.auth
.refresh()
.then(() => {
authenticated = true;
})
.catch(() => {});
// Let's login in case we don't have token or it is invalid / expired
while (!authenticated) {
const email = window.prompt('Email:');
const password = window.prompt('Password:');
await directus.auth
.login({ email, password })
.then(() => {
authenticated = true;
})
.catch(() => {
window.alert('Invalid credentials');
});
}
// GET DATA
// After authentication, we can fetch data from any collections that the user has permissions to.
const privateData = await directus.items('some_private_collection').readByQuery({ sort: ['id'] });
console.log(privateData.data);
}
start();
Custom Configuration
The previous section covered basic installation and usage of the JS SDK with default configurations for init. But
sometimes you may need to customize these defaults.
Constructor
import { Directus } from '@directus/sdk';
const directus = new Directus(url, init);
Parameters
url required
- Type —
String - Description — A string that points to your Directus instance. E.g.,
https://example.directus.io - Default — N/A
init optional
- Type —
Object - Description — Defines authentication, storage and transport settings.
- Default — The following shows the default values for
init.
// This is the default init object
const config = {
auth: {
mode: 'cookie', // 'json' in Node.js
autoRefresh: true,
msRefreshBeforeExpires: 30000,
staticToken: '',
},
storage: {
prefix: '',
mode: 'LocalStorage', // 'MemoryStorage' in Node.js
},
transport: {
params: {},
headers: {},
onUploadProgress: (ProgressEvent) => {},
maxBodyLength: null,
maxContentLength: null,
},
};
Customize auth
Defines how authentication is handled by the SDK. By default, Directus creates an instance of auth which handles
refresh tokens automatically.
const auth = {
mode: 'cookie', // 'json' in Node.js
autoRefresh: true,
msRefreshBeforeExpires: 30000,
staticToken: '',
};
Options
mode
- Type —
String - Description — Defines the mode you want to use for authentication. It can be
'cookie'for cookies or'json'for JWT. - Default — Defaults to
'cookie'on browsers and'json'otherwise.
:::tip
We recommend using cookies when possible to prevent any kind of attacks, mostly XSS.
:::
autoRefresh
- Type —
Boolean - Description — Determines whether SDK handles refresh tokens automatically.
- Default — Defaults to
true.
msRefreshBeforeExpires
- Type —
Number - Description — When
autoRefreshis enabled, this tells how many milliseconds before the refresh token expires and needs to be refreshed. - Default — Defaults to
30000.
staticToken
- Type —
String - Description - Defines the static token to use. It is not compatible with the options above since it does not refresh.
- Default — Defaults to
''(no static token).
Extend auth
It is possible to provide a custom implementation by extending IAuth. While this could be useful in certain advanced
situations, it is not needed for most use-cases.
import { IAuth, Directus } from '@directus/sdk';
class MyAuth extends IAuth {
async login() {
return { access_token: '', expires: 0 };
}
async logout() {}
async refresh() {
return { access_token: '', expires: 0 };
}
async static() {
return true;
}
}
const directus = new Directus('https://example.directus.app', {
auth: new MyAuth(),
});
Customize storage
The storage is used to load and save token information. By default, Directus creates an instance of storage which
handles store information automatically.
const storage = {
prefix: '',
mode: 'LocalStorage', // 'MemoryStorage' in Node.js
};
:::tip Multiple Instances
If you want to use multiple instances of the SDK you should set a different prefix for each one.
:::
::: tip
The axios instance can be used for custom requests by calling:
await directus.transport<method>('/path/to/endpoint', {
/* body, params, ... */
});
:::
Options
prefix
- Type —
String - Description — Defines the tokens prefix tokens that are saved. This should be fulfilled with different values when using multiple instances of SDK.
- Default — Defaults to
''(no prefix).
mode
- Type —
String - Description — Defines the storage location to be used to save tokens. Allowed values are
LocalStorageandMemoryStorage. The modeLocalStorageis not compatible with Node.js.MemoryStorageis not persistent, so once you leave the tab or quit the process, you will need to authenticate again. - Default — Defaults to
LocalStorageon browsers andMemoryStorageon Node.js.
Extend storage
It is possible to provide a custom implementation by extending BaseStorage. While this could be useful in certain
advanced situations, it is not needed for most use-cases.
import { BaseStorage, Directus } from '@directus/sdk';
class SessionStorage extends BaseStorage {
get(key) {
return sessionStorage.getItem(key);
}
set(key, value) {
return sessionStorage.setItem(key, value);
}
delete(key) {
return sessionStorage.removeItem(key);
}
}
const directus = new Directus('https://example.directus.app', {
storage: new SessionStorage(),
});
Customize transport
Defines settings you want to customize regarding Transport.
By default, Directus creates an instance of Transport which handles requests automatically. It uses
axios so it is compatible in both browsers and Node.js. With axios, it is also possible to
handle upload progress (a downside of fetch).
The configurations within init.transport are passed to axios. For more details, see
Request Config in the axios documentation.
export default {
params: {},
headers: {},
onUploadProgress: (ProgressEvent) => {},
maxBodyLength: null,
maxContentLength: null,
};
Options
params
- Type —
Object - Description — Defines an object with keys and values to be passed as additional query string.
- Default — N/A
headers
- Type —
Object - Description - Defines an object with keys and values to be passed as additional headers.
- Default — N/A
onUploadProgress
- Type —
Function - Description — Defines a callback function to indicate the upload progress.
- Default — N/A
:::tip ProgressEvent Please see the MDN documentation to learn more about the ProgressEvent.
:::
maxBodyLength
- Type —
Number - Description — The maximum body length in bytes. Set
Infinityfor no limit. - Default — N/A
maxContentLength
- Type —
Number - Description — The maximum content length in bytes. Set
Infinityfor no limit. - Default — N/A
Extend Transport
It is possible to provide a custom implementation by extending ITransport. For example, you can customize it to use
different HTTP libraries. While this could be useful in certain advanced situations, it is not needed for most
use-cases.
import { ITransport, Directus } from '@directus/sdk';
class MyTransport extends ITransport {
buildResponse() {
return {
raw: '',
data: {},
status: 0,
headers: {},
};
}
async get(path, options) {
return this.buildResponse();
}
async head(path, options) {
return this.buildResponse();
}
async options(path, options) {
return this.buildResponse();
}
async delete(path, data, options) {
return this.buildResponse();
}
async post(path, data, options) {
return this.buildResponse();
}
async put(path, data, options) {
return this.buildResponse();
}
async patch(path, data, options) {
return this.buildResponse();
}
}
const directus = new Directus('https://example.directus.app', {
transport: new MyTransport(),
});
TypeScript
Version >= 4.1
Although it's not required, it is recommended to use TypeScript to have an easy development experience. This allows more detailed IDE suggestions for return types, sorting, filtering, etc.
To feed the SDK with your current schema, you need to pass it on the constructor.
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>('https://example.directus.app');
// ...
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.
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://example.directus.app');
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';
Authentication
Get current token
await directus.auth.token;
::: warning Async
Reading the token is an asynchronous getter. This makes sure that any currently active refresh calls are being awaited
before the current token is returned.
:::
Login
With credentials
await directus.auth.login({
email: 'admin@example.com',
password: 'd1r3ctu5',
});
With static tokens
await directus.auth.static('static_token');
Refresh Auth Token
By default, Directus will handle token refreshes. Although, you can handle this behavior manually by setting
autoRefresh to false.
await directus.auth.refresh();
::: tip Developing Locally
If you're developing locally, you might not be able to refresh your auth token automatically in all browsers. This is because the default auth configuration requires secure cookies to be set, and not all browsers allow this for localhost. You can use a browser which does support this such as Firefox, or disable secure cookies.
:::
Logout
await directus.auth.logout();
Request a Password Reset
By default, the address defined in PUBLIC_URL on .env file is used for the link to the reset password page sent in
the email:
await directus.auth.password.request('admin@example.com');
But a custom address can be passed as second argument:
await directus.auth.password.request(
'admin@example.com',
'https://myapp.com' // In this case, the link will be https://myapp.com?token=FEE0A...
);
Note: To use a custom address you need to configure the
PASSWORD_RESET_URL_ALLOW_LIST environment variable to enable this feature.
Reset a Password
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()
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
// import { Directus, ID } from '@directus/sdk';
const { Directus } = require('@directus/sdk');
const directus = new Directus('https://example.directus.app');
const articles = directus.items('articles');
TypeScript
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://example.directus.app');
// typeof(article) is a partial "Article"
await directus.items('articles').readOne(10);
// Error TS2322: "hello" is not assignable to type "boolean".
// post.published = 'hello';
Create Single Item
await articles.createOne({
title: 'My New Article',
});
Create Multiple Items
await articles.createMany([
{
title: 'My First Article',
},
{
title: 'My Second Article',
},
]);
Read By Query
await articles.readByQuery({
search: 'Directus',
filter: {
date_published: {
_gte: '$NOW',
},
},
});
Read All
await articles.readByQuery({
// By default API limits results to 100.
// With -1, it will return all results, but it may lead to performance degradation
// for large result sets.
limit: -1,
});
Read Single Item
await articles.readOne(15);
Supports optional query:
await articles.readOne(15, {
fields: ['title'],
});
Read Multiple Items
await articles.readMany([15, 16, 17]);
Supports optional query:
await articles.readMany([15, 16, 17], {
fields: ['title'],
});
Update Single Item
await articles.updateOne(15, {
title: 'This articles now has a different title',
});
Supports optional query:
await articles.updateOne(
42,
{
title: 'This articles now has a similar title',
},
{
fields: ['title'],
}
);
Update Multiple Items
await articles.updateMany([15, 42], {
title: 'Both articles now have the same title',
});
Supports optional query:
await articles.updateMany(
[15, 42],
{
title: 'Both articles now have the same title',
},
{
fields: ['title'],
}
);
Delete
// One
await articles.deleteOne(15);
// Multiple
await articles.deleteMany([15, 42]);
Request Parameter Overrides
To override any of the axios request parameters, provide an additional parameter with a requestOptions object:
await articles.createOne(
{ title: 'example' },
{ fields: ['id'] },
{
requestOptions: {
headers: {
'X-My-Custom-Header': 'example',
},
},
}
);
Activity
directus.activity;
The activity property has all the methods of directus.items('directus_activity') with the addition of an alias to the activity comments (below).
directus.activity.comments;
Comments
directus.comments;
Create a comment
await directus.comments.create({
// ...
});
Update a comment
await directus.comments.update(/* comment activity id */ 15, 'Yo, dawg!');
Delete a comment
await directus.comments.delete(/* comment activity id */ 15);
Collections
directus.collections;
Read a single collection
await directus.collections.readOne(/* collection name */ 'articles');
Read all collections
await directus.collections.readAll(); //does not currently support query or searching
Create a collection
await directus.collections.createOne({ collection: 'articles', /* ... */ });
Create multiple collections
await directus.collections.createMany([{ collection: 'articles', /* ... */ }, /* ... */]);
Update a collection
await directus.collections.updateOne(/* collection name */ 'articles', /* patch */ { note: 'All the articles' }, query);
Delete a collection
await directus.collections.deleteOne(/* collection name */ 'articles');
Fields
directus.fields;
Read a single field
await directus.fields.readOne(/* collection name */ 'articles', /* id of the field */ 15);
Read multiple fields
await directus.fields.readMany(/* collection name */ 'articles'); //doesn't currently support query parameter
Read all fields
await directus.fields.readAll(); //does not currently support query or searching
Create a field
await directus.fields.createOne(/* collection name */ 'articles', { field: 'alt_title', /* ... */ });
Update a field
await directus.fields.updateOne(
/* collection name */ 'articles',
/* field_name */ 'alt_title',
/* patch */ { hidden: true }
);
Delete a field
await directus.fields.deleteOne(/* collection name */ 'articles', /* field_name */ 'alt_title');
Files
directus.files;
The files property support all of the functions common to all items - directus.items('directus_files') with one addition: import.
Import
In addition to the items common methods, the files property adds the import method for importing files.
directus.files.import(/* ... */);
See API File Import
Uploading a file
To upload a file you will need to send a multipart/form-data as body. On browser side you do so:
/* index.js */
import { Directus } from 'https://unpkg.com/@directus/sdk@latest/dist/sdk.esm.min.js';
const directus = new Directus('https://example.directus.app', {
auth: {
staticToken: 'STATIC_TOKEN', // If you want to use a static token, otherwise check below how you can use email and password.
},
});
// await directus.auth.login({ email, password })
// If you want to use email and password, remove the staticToken above.
const form = document.querySelector('#upload-file');
if (form && form instanceof HTMLFormElement) {
form.addEventListener('submit', async (event) => {
event.preventDefault();
const form = new FormData(event.target);
await directus.files.createOne(form);
});
}
<!-- index.html -->
<html>
<head></head>
<body>
<form id="upload-file">
<input type="text" name="title" />
<input type="file" name="file" />
<button>Send</button>
</form>
<script src="/index.js" type="module"></script>
</body>
</html>
NodeJS usage
When uploading a file from a NodeJS environment, you'll have to override the headers to ensure the correct boundary is set:
import { Directus } from 'https://unpkg.com/@directus/sdk@latest/dist/sdk.esm.min.js';
const directus = new Directus('https://example.directus.app', {
auth: {
staticToken: 'STATIC_TOKEN', // If you want to use a static token, otherwise check below how you can use email and password.
},
});
const form = new FormData();
form.append('file', fs.createReadStream('./to_upload.jpeg'));
await directus.files.createOne(
form,
{},
{
requestOptions: {
headers: {
...form.getHeaders(),
},
},
}
);
Importing a file
Example of importing a file from a URL:
await directus.files.import({
url: 'http://www.example.com/example-image.jpg',
});
Example of importing file with custom data:
await directus.files.import({
url: 'http://www.example.com/example-image.jpg',
data: {
title: 'My Custom File',
},
});
Folders
directus.folders;
Same methods as directus.items("directus_folders").
Permissions
directus.permissions;
Same methods as directus.items("directus_permissions").
Presets
directus.presets;
Same methods as directus.items("directus_presets").
Relations
directus.relations;
Same methods as directus.items("directus_relations").
Revisions
directus.revisions;
Same methods as directus.items("directus_revisions").
Roles
directus.roles;
Same methods as directus.items("directus_roles").
Settings
directus.settings;
Same methods as directus.items("directus_settings").
Server
Ping the Server
await directus.server.ping();
Get Server/Project Info
await directus.server.info();
Users
directus.users;
Same methods as directus.items("directus_users"), and:
Invite a New User
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
await directus.users.invites.accept('<accept-token>', 'n3w-p455w0rd');
The provided token is sent to the user's email
Enable Two-Factor Authentication
await directus.users.tfa.enable('my-password');
Disable Two-Factor Authentication
await directus.users.tfa.disable('691402');
Get the Current User
await directus.users.me.read();
Supports optional query:
await directus.users.me.read({
fields: ['last_access'],
});
Update the Current Users
await directus.users.me.update({ first_name: 'Admin' });
Supports optional query:
await directus.users.me.update({ first_name: 'Admin' }, { fields: ['last_access'] });
Utils
Get a Random String
await directus.utils.random.string();
Supports an optional length (defaults to 32):
await directus.utils.random.string(50);
Generate a Hash for a Given Value
await directus.utils.hash.generate('My String');
Verify if a Hash is Valid
await directus.utils.hash.verify('My String', '$argon2i$v=19$m=4096,t=3,p=1$A5uogJh');
Sort Items in a Collection
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
await directus.utils.revert(451);
Note: The key passed is the primary key of the revision you'd like to apply.