Installation
npm install @directus/sdk
Basic Usage
这是使用 JS SDK 的起点。 创建 Directus 实例后,您可以开始从中调用方法来访问您的项目和数据。
import { Directus } from '@directus/sdk'
const directus = new Directus('http://directus.example.com')
您始终可以访问 公共角色 可用的数据.
async function publicData() {
// GET DATA
// 我们不需要验证 public 角色是否可以访问 some_public_collection。
const publicData = await directus.items('some_public_collection').readByQuery({ sort: ['id'] })
console.log(publicData.data)
}
Basic Authentication
async function start() {
// 验证
let authenticated = false
// 如果存在,尝试使用令牌进行身份验证
await directus.auth
.refresh()
.then(() => {
authenticated = true
})
.catch(() => {})
// 让我们登录以防我们没有令牌或者它无效/过期
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')
})
}
// 获取数据
// 身份验证后,我们可以从用户有权访问的任何集合中获取数据。
const privateData = await directus.items('some_private_collection').readByQuery({ sort: ['id'] })
console.log(publicData.data)
}
start()
Custom Configuration
上一节介绍了 JS SDK 的基本安装和使用,以及 init
的默认配置。 但有时您可能需要自定义这些默认值。
Constructor
import { Directus } from '@directus/sdk'
const directus = new Directus(url, init)
Parameters
url
required
- Type —
String
- Description — 指向您的 Directus 实例的字符串。 例如,
https://example.directus.io
- Default — N/A
init
optional
- Type —
Object
- Description — 定义身份验证、存储和传输设置。
- Default — 下面显示了
init
的默认值。
// 这是默认的初始化对象
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
定义 SDK 如何处理身份验证。 默认情况下,Directus 创建一个自动处理刷新令牌的 auth
实例。
const auth = {
mode: 'cookie', // 'json' in Node.js
autoRefresh: true,
msRefreshBeforeExpires: 30000,
staticToken: '',
}
Options
mode
- Type —
String
- Description — 定义您要用于身份验证的模式。 它可以是用于 cookie 的
'cookie'
或用于 JWT 的'json'
。 - Default — 在浏览器上默认为
cookie
,否则默认为json
。
我们建议尽可能使用 cookie 来防止任何类型的攻击,主要是 XSS。
autoRefresh
- Type —
Boolean
- Description — 确定 SDK 是否自动处理刷新令牌。
- Default — 默认是:
true
.
msRefreshBeforeExpires
- Type —
Number
- Description —当启用
autoRefresh
时,这会告诉刷新令牌过期和需要刷新之前的毫秒数。 - Default — 默认是:
30000
.
staticToken
- Type —
String
- Description - 定义要使用的静态令牌。 它与上述选项不兼容,因为它不刷新。
- Default — 默认是:
''
(no static token).
Extend auth
可以通过扩展 IAuth
来提供自定义实现。 虽然这在某些高级情况下可能很有用,但对于大多数用例来说并不需要。
import { Directus, IAuth } 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
存储用于加载和保存令牌信息。 默认情况下,Directus 创建一个自动处理存储信息的 storage
实例。
const storage = {
prefix: '',
mode: 'LocalStorage', // 'MemoryStorage' in Node.js
}
多个实例
如果您想使用 SDK 的多个实例,您应该为每个实例设置不同的 prefix
。
axios 实例可用于自定义请求,方法是调用:
await directus.transport.<method>('/path/to/endpoint', {
/* body, params, ... */
});
Options
prefix
- Type —
String
- Description — 定义保存的令牌前缀令牌。 当使用多个 SDK 实例时,这应该用不同的值来实现。
- Default — 默认是:
''
(no prefix).
mode
- Type —
String
- Description — 定义用于保存令牌的存储位置。 允许的值为
LocalStorage
和MemoryStorage
。LocalStorage
模式与 Node.js 不兼容。MemoryStorage
不是永久性的,所以一旦离开选项卡或退出进程,您将需要再次进行身份验证。 - Default — 在浏览器上默认为
LocalStorage
,在 Node.js 上默认为MemoryStorage
。
Extend storage
可以通过扩展 BaseStorage 来提供自定义实现。 虽然这在某些高级情况下可能很有用,但对于大多数用例来说并不需要。
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
定义要自定义的有关 Transport 的设置。
默认情况下,Directus 创建一个自动处理请求的 Transport 实例。 它使用 axios
,因此它在浏览器和 Node.js 中都兼容。 使用 axios,还可以处理上传进度(fetch
的缺点)。
init.transport
中的配置被传递给 axios
。 更多详细信息,请参见axios文档中的Request Config。
export default {
params: {},
headers: {},
onUploadProgress: (ProgressEvent) => {},
maxBodyLength: null,
maxContentLength: null,
}
Options
params
- Type —
Object
- Description — 定义一个对象,其中包含要作为附加查询字符串传递的键和值。
- Default — N/A
headers
- Type —
Object
- Description - 定义一个对象,其中包含要作为附加标头传递的键和值。
- Default — N/A
onUploadProgress
- Type —
Function
- Description — 定义一个回调函数来指示上传进度。
- Default — N/A
ProgressEvent 请参阅 MDN 文档以了解有关ProgressEvent.
maxBodyLength
- Type —
Number
- Description — 以字节为单位的最大正文长度。 设置
Infinity
表示没有限制。 - Default — N/A
maxContentLength
- Type —
Number
- Description — 以字节为单位的最大内容长度。 设置
Infinity
表示没有限制。 - Default — N/A
Extend Transport
可以通过扩展“ITransport”来提供自定义实现。 例如,您可以自定义它以使用不同的 HTTP 库。 虽然这在某些高级情况下可能很有用,但对于大多数用例来说并不需要。
import { Directus, ITransport } 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
虽然不是必需的,但建议使用 TypeScript 以获得轻松的开发体验。 这允许对返回类型、排序、过滤等提供更详细的 IDE 建议。
要为 SDK 提供当前架构,您需要将其传递给构造函数。
interface BlogPost {
id: ID
title: string
}
interface BlogSettings {
display_promotions: boolean
}
interface MyCollections {
posts: BlogPost
settings: BlogSettings
}
// 这就是您向 Directus 提供自定义类型信息的方式。
const directus = new Directus<MyCollections>('https://example.directus.app')
// ...
const post = await directus.items('posts').readOne(1)
// typeof(post) 是部分 BlogPost 对象
const settings = await posts.singleton('settings').read()
// typeof(settings) 是部分 BlogSettings 对象
您还可以通过为系统集合提供类型信息来扩展 Directus 系统类型信息。
import { Directus } from '@directus/sdk'
// 添加到 Directus 用户集合的自定义字段。
interface UserType {
level: number
experience: number
}
interface CustomTypes {
/*
此类型将与 Directus 用户类型合并。 命名与 directus 集合名称完全匹配很重要。 在这里不会发现拼写错误,因为 SDK 会假定它是自定义用户集合。
*/
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
// 错误 TS2322:类型“字符串”不可分配给类型“数字”。
me.experience = 'high'
Authentication
Get current token
const token = await directus.auth.token
异步
读取令牌是一个异步获取器。 这确保在返回当前令牌之前等待任何当前活动的refresh
调用。
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
默认情况下,Directus 将处理令牌刷新。 不过,您可以通过将 autoRefresh
设置为 false
来手动处理此行为。
await directus.auth.refresh()
本地开发
如果您在本地进行开发,您可能无法在所有浏览器中自动刷新您的身份验证令牌。 这是因为默认的身份验证配置需要设置安全 cookie,并且并非所有浏览器都允许本地主机这样做。 您可以使用支持此功能的浏览器,例如 Firefox,或 禁用安全 cookie。
Logout
await directus.auth.logout()
Request a Password Reset
默认情况下,在 .env 文件的 PUBLIC_URL 中定义的地址用于链接到发送的重置密码页面 电子邮件:
await directus.auth.password.request('admin@example.com')
但是自定义地址可以作为第二个参数传递:
await directus.auth.password.request(
'admin@example.com',
'https://myapp.com' // In this case, the link will be https://myapp.com?token=FEE0A...
)
Note: 要使用自定义地址,您需要配置 PASSWORD_RESET_URL_ALLOW_LIST
环境变量 以启用此功能。
Reset a Password
await directus.auth.password.reset('abc.def.ghi', 'n3w-p455w0rd')
注意:在第一个参数中传递的令牌在使用 request()
时通过电子邮件发送给用户
Items
您可以通过向 items 函数提供集合(和类型,在 TypeScript 的情况下)来获取项目处理程序的实例。 以下示例将使用Article
类型。
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'
// 根据其字段映射您的集合结构。
interface Article {
id: ID
title: string
body: string
published: boolean
}
// 将您的集合映射到其各自的类型。 SDK 稍后会根据使用情况推断其类型。
interface MyBlog {
// [collection_name]: typescript_type
articles: Article
// 您还可以扩展 Directus 集合。 命名必须与 Directus 系统集合相匹配,它将被合并到系统规范中。
directus_users: {
bio: string
}
}
// 让 SDK 了解您的集合类型。
const directus = new Directus<MyBlog>('https://example.directus.app')
// typeof(article) 是部分“文章”
const article = await directus.items('articles').readOne(10)
// 错误 TS2322:“hello”不可分配给类型“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({
// 默认情况下,API 将结果限制为 100。
// 设置为-1,会返回所有结果,但是对于大的结果集可能会导致性能下降。
limit: -1,
})
Read Single Item
await articles.readOne(15)
支持可选查询:
await articles.readOne(15, {
fields: ['title'],
})
Read Multiple Items
await articles.readMany([15, 16, 17])
支持可选查询:
await articles.readMany([15, 16, 17], {
fields: ['title'],
})
Update Single Item
await articles.updateOne(15, {
title: 'This articles now has a different title',
})
支持可选查询:
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',
})
支持可选查询:
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
要覆盖任何 axios 请求参数,请提供带有 requestOptions
对象的附加参数:
await articles.createOne(
{ title: 'example' },
{ fields: ['id'] },
{
requestOptions: {
headers: {
'X-My-Custom-Header': 'example',
},
},
}
)
Activity
directus.activity
与directus.items("directus_activity")
相同的方法.
Comments
directus.comments
与directus.items("directus_comments")
相同的方法.
Collections
directus.collections
与directus.items("directus_collections")
相同的方法.
Fields
directus.fields
与directus.items("directus_fields")
相同的方法.
Files
directus.files
与directus.items("directus_files")
相同的方法.
Uploading a file
要上传文件,您需要发送一个 multipart/form-data
作为正文。 在浏览器端你这样做:
/* 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', // 如果您想使用静态令牌,请在下方查看如何使用电子邮件和密码。
},
})
// await directus.auth.login({ email, password }) 如果要使用邮箱和密码,去掉上面的staticToken。
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 -->
<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
从 NodeJS 环境上传文件时,您必须覆盖标头以确保设置正确的边界:
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', // 如果您想使用静态令牌,请在下方查看如何使用电子邮件和密码。
},
});
const form = new FormData();
form.append("file", fs.createReadStream("./to_upload.jpeg"));
const fileId = 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',
})
使用自定义数据导入文件的示例:
await directus.files.import({
url: 'http://www.example.com/example-image.jpg',
data: {
title: 'My Custom File',
},
})
Folders
directus.folders
与directus.items("directus_folders")
相同的方法。
Permissions
directus.permissions
与directus.items("directus_permissions")
相同的方法。
Presets
directus.presets
与directus.items("directus_presets")
相同的方法。
Relations
directus.relations
与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
与 directus.items("directus_users")
相同的方法, and:
Invite a New User
await directus.users.invites.send('admin@example.com', 'fe38136e-52f7-4622-8498-112b8a32a1e2')
第二个参数是用户的角色
Accept a User Invite
await directus.users.invites.accept('<accept-token>', 'n3w-p455w0rd')
提供的令牌被发送到用户的电子邮件
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()
支持可选查询:
await directus.users.me.read({
fields: ['last_access'],
})
Update the Current Users
await directus.users.me.update({ first_name: 'Admin' })
支持可选查询:
await directus.users.me.update({ first_name: 'Admin' }, { fields: ['last_access'] })
Utils
Get a Random String
await directus.utils.random.string()
支持可选的“长度”(默认为 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)
这会将项目“15”移动到项目“42”的位置,并将一个“槽”之间的所有内容向上移动。
Revert to a Previous Revision
await directus.utils.revert(451)
注意:传递的键是您要应用的修订的主键。