Skip to main content

管理 API SDK

概述

¥Overview

@prisma/management-api-sdkPrisma 数据平台管理 API 的 TypeScript SDK。使用简单的客户端直接访问 API,或使用内置 OAuth 身份验证和自动令牌刷新功能的完整 SDK。

¥The @prisma/management-api-sdk is a TypeScript SDK for the Prisma Data Platform Management API. Use the simple client for direct API access, or the full SDK with built-in OAuth authentication and automatic token refresh.

基于 公开的 OpenAPI 3.1 规范

¥Based on the public OpenAPI 3.1 specification.

安装

¥Installation

npm install @prisma/management-api-sdk

基本用法

¥Basic usage

用于现有访问权限或 服务令牌

¥For usage with an existing access or service token.

发起 API 调用

¥Making API calls

客户端为所有 API 端点提供完全类型化的方法:

¥The client provides fully typed methods for all API endpoints:

import { createManagementApiClient } from '@prisma/management-api-sdk'

const client = createManagementApiClient({
token: 'your-access-token',
})

// List workspaces
const { data: workspaces, error } = await client.GET('/v1/workspaces')

// Get a specific project
const { data: project } = await client.GET('/v1/projects/{id}', {
params: { path: { id: 'project-id' } },
})

// Create a new project
const { data: newProject } = await client.POST('/v1/workspaces/{workspaceId}/projects', {
params: { path: { workspaceId: 'workspace-id' } },
body: { name: 'My New Project' },
})

// Create a new database
const { data: newDatabase } = await client.POST('/v1/projects/{projectId}/databases', {
params: { path: { projectId: 'project-id' } },
body: {
name: 'my-new-db-instance',
region: 'us-east-1',
isDefault: true,
},
})

// Delete a database
const { error: deleteError } = await client.DELETE('/v1/databases/{databaseId}', {
params: { path: { databaseId: 'database-id' } },
})

自定义客户端

¥Customizing the client

你可以从 openapi-fetch 中覆盖任何 ClientOptions,包括 baseUrlheaders 和其他获取选项:

¥You can override any ClientOptions from openapi-fetch, including baseUrl, headers, and other fetch options:

import { createManagementApiClient } from '@prisma/management-api-sdk'

// Override baseUrl and add custom headers
const client = createManagementApiClient({
token: 'your-access-token',
baseUrl: 'https://api.example.com',
headers: {
'X-Custom-Header': 'value',
},
})
注意

如果你提供如果同时设置了 tokenheaders.Authorization,则 headers.Authorization 优先。如果未提供 baseUrl,则默认使用 https://api.prisma.io

¥If you provide both token and headers.Authorization, the headers.Authorization takes precedence. The baseUrl defaults to https://api.prisma.io if not provided.

高级用法

¥Advanced usage

对于需要 OAuth 身份验证、自动令牌刷新和令牌存储管理的应用,请使用完整 SDK。

¥For applications that need OAuth authentication, automatic token refresh, and token storage management, use the full SDK.

OAuth 身份验证流程

¥OAuth authentication flow

SDK 使用 OAuth 2.0 和 PKCE 进行安全身份验证。流程是无状态的 - 你需要负责在登录 URL 生成和回调处理之间存储 stateverifier

¥The SDK uses OAuth 2.0 with PKCE for secure authentication. The flow is stateless - you're responsible for storing the state and verifier between the login URL generation and callback handling.

1. 创建 SDK 实例

¥ Create the SDK instance

import { createManagementApiSdk, type TokenStorage } from '@prisma/management-api-sdk'

// Implement token storage for your environment
const tokenStorage: TokenStorage = {
async getTokens() {
const stored = localStorage.getItem('prisma-tokens')
return stored ? JSON.parse(stored) : null
},
async setTokens(tokens) {
localStorage.setItem('prisma-tokens', JSON.stringify(tokens))
},
async clearTokens() {
localStorage.removeItem('prisma-tokens')
},
}

// Create the SDK instance
const api = createManagementApiSdk({
clientId: 'your-oauth-client-id',
redirectUri: 'https://your-app.com/auth/callback',
tokenStorage,
})

2. 登录

¥ Initiate login

生成 OAuth 登录 URL。必须存储返回的 stateverifier(例如,存储在会话或 cookie 中),以便在处理回调时使用:

¥Generate the OAuth login URL. The returned state and verifier must be stored (e.g., in a session or cookie) for use when handling the callback:

const { url, state, verifier } = await api.getLoginUrl({
scope: 'workspace:admin offline_access',
additionalParams: {
utm_source: 'my-app',
utm_medium: 'login',
},
})

// Store state and verifier for the callback (e.g., in session storage)
sessionStorage.setItem('oauth-state', state)
sessionStorage.setItem('oauth-verifier', verifier)

// Redirect user to the login URL
window.location.href = url

3. 处理回调

¥ Handle the callback

当用户被重定向回你的应用时,检索存储的 stateverifier,并将它们传递给 handleCallback。成功后,令牌将通过你的 tokenStorage 实现自动存储:

¥When the user is redirected back to your app, retrieve the stored state and verifier and pass them to handleCallback. On success, tokens are automatically stored via your tokenStorage implementation:

// In your callback route handler
const callbackUrl = window.location.href

// Retrieve the stored values
const expectedState = sessionStorage.getItem('oauth-state')
const verifier = sessionStorage.getItem('oauth-verifier')

// Clean up stored values
sessionStorage.removeItem('oauth-state')
sessionStorage.removeItem('oauth-verifier')

try {
await api.handleCallback({
callbackUrl,
verifier,
expectedState,
})

// Tokens are now stored in tokenStorage and the client is ready to use
console.log('Login successful!')
} catch (error) {
if (error instanceof AuthError) {
console.error('Authentication failed:', error.message)
}
}

4. 发起 API 调用

¥ Make API calls

客户端会自动包含身份验证标头,并在令牌过期时刷新令牌:

¥The client automatically includes authentication headers and refreshes tokens when they expire:

// List workspaces
const { data: workspaces } = await api.client.GET('/v1/workspaces')

// Get a specific project
const { data: project } = await api.client.GET('/v1/projects/{id}', {
params: { path: { id: 'project-id' } },
})

// Create a new project
const { data: newProject } = await api.client.POST('/v1/workspaces/{workspaceId}/projects', {
params: { path: { workspaceId: 'workspace-id' } },
body: { name: 'My Project' },
})

// Create a new database
const { data: newDatabase } = await api.client.POST('/v1/projects/{projectId}/databases', {
params: { path: { projectId: 'project-id' } },
body: {
name: 'production',
region: 'us-east-1',
isDefault: true,
},
})

// Delete a database
const { error: deleteError } = await api.client.DELETE('/v1/databases/{databaseId}', {
params: { path: { databaseId: 'database-id' } },
})

5. 注销

¥ Logout

await api.logout() // Clears stored tokens

令牌存储接口

¥Token storage interface

实现此接口以处理环境中的令牌持久性:

¥Implement this interface to handle token persistence in your environment:

interface TokenStorage {
/** Provide the stored tokens to the SDK */
getTokens(): Promise<Tokens | null>
/** Store new or updated tokens when the SDK has successfully authenticated or refreshed tokens */
setTokens(tokens: Tokens): Promise<void>
/** Clear the tokens when the user logs out or the refresh token is invalid */
clearTokens(): Promise<void>
}

type Tokens = {
/** The workspace ID that these tokens are valid for (extracted from the access token) */
workspaceId: string
/** The access token for API requests */
accessToken: string
/** The refresh token for obtaining new access tokens (only present if scope includes 'offline_access') */
refreshToken?: string
}

示例:VS Code 扩展

¥Example: VS Code Extension

const tokenStorage: TokenStorage = {
async getTokens() {
const workspaceId = await context.secrets.get('workspaceId')
const accessToken = await context.secrets.get('accessToken')
const refreshToken = await context.secrets.get('refreshToken')

if (!workspaceId || !accessToken) return null

return { workspaceId, accessToken, refreshToken: refreshToken || undefined }
},
async setTokens(tokens) {
await context.secrets.store('workspaceId', tokens.workspaceId)
await context.secrets.store('accessToken', tokens.accessToken)
if (tokens.refreshToken) {
await context.secrets.store('refreshToken', tokens.refreshToken)
}
},
async clearTokens() {
await context.secrets.delete('workspaceId')
await context.secrets.delete('accessToken')
await context.secrets.delete('refreshToken')
},
}

示例:Node.js CLI

¥Example: Node.js CLI

import { readFile, writeFile, unlink } from 'node:fs/promises'
import { homedir } from 'node:os'
import { join } from 'node:path'

const tokenPath = join(homedir(), '.prisma', 'credentials.json')

const tokenStorage: TokenStorage = {
async getTokens() {
try {
const data = await readFile(tokenPath, 'utf-8')
return JSON.parse(data)
} catch {
return null
}
},
async setTokens(tokens) {
await writeFile(tokenPath, JSON.stringify(tokens, null, 2))
},
async clearTokens() {
await unlink(tokenPath).catch(() => {})
},
}

示例:无状态 Web 服务器

¥Example: Stateless Web Server

对于无状态 Web 服务器(无服务器、负载均衡),请将 PKCE 状态存储在加密的 cookie 或数据库中:

¥For stateless web servers (serverless, load-balanced), store the PKCE state in an encrypted cookie or database:

// In your login route
app.get('/login', async (req, res) => {
const { url, state, verifier } = await api.getLoginUrl({
scope: 'workspace:admin offline_access',
})

// Store in encrypted cookie or database keyed by state
res.cookie('oauth-verifier', verifier, { httpOnly: true, secure: true, signed: true })
res.cookie('oauth-state', state, { httpOnly: true, secure: true, signed: true })

res.redirect(url)
})

// In your callback route
app.get('/callback', async (req, res) => {
const verifier = req.signedCookies['oauth-verifier']
const expectedState = req.signedCookies['oauth-state']

// Clear cookies
res.clearCookie('oauth-verifier')
res.clearCookie('oauth-state')

await api.handleCallback({ callbackUrl: req.url, verifier, expectedState })

// Tokens are now stored in tokenStorage
// ... handle successful login
})

自动令牌刷新

¥Automatic token refresh

当刷新令牌可用时,SDK 会自动处理令牌刷新(需要 offline_access 权限):

¥The SDK automatically handles token refresh when a refresh token is available (requires offline_access scope):

  • 当请求返回 401 时,SDK 会使用刷新令牌刷新访问令牌。

    ¥When a request returns 401, the SDK refreshes the access token using the refresh token

  • 刷新期间的并发请求将被排队,并在刷新完成后进行处理。

    ¥Concurrent requests during refresh are queued and resolved once refresh completes

  • 如果由于刷新令牌无效而导致刷新失败,则会清除令牌并抛出 AuthError 异常,并显示消息 refreshTokenInvalid: true

    ¥If refresh fails due to an invalid refresh token, tokens are cleared and AuthError is thrown with refreshTokenInvalid: true

  • 如果没有可用的刷新令牌,则会抛出 AuthError 异常,并显示消息“没有可用的刷新令牌”。请重新登录。

    ¥If no refresh token is available, an AuthError is thrown with the message "No refresh token available. Please log in again."

API 参考

¥API reference

createManagementApiClient(options)

创建一个不带身份验证处理的原始 API 客户端。如果你希望自行管理身份验证或使用服务令牌,这将非常有用。

¥Creates a raw API client without authentication handling. Useful if you want to manage authentication yourself or use a service token.

参数:

¥Parameters:

  • options.token?: string - 访问令牌(自动转换为 Authorization: Bearer ${token} 标头)

    ¥options.token?: string - Access token (automatically converted to Authorization: Bearer ${token} header)

  • options.baseUrl?: string - API 请求的基本 URL(默认为 https://api.prisma.io

    ¥options.baseUrl?: string - Base URL for API requests (defaults to https://api.prisma.io)

  • options.headers?: Record<string, string> - 附加标头

    ¥options.headers?: Record<string, string> - Additional headers

  • 也支持 openapi-fetch 中的其他 ClientOptions

    ¥Other ClientOptions from openapi-fetch are also supported

返回值:一个用于发出请求的类型化 API 客户端。

¥Returns: A typed API client for making requests.

createManagementApiSdk(config)

创建一个具有 OAuth 身份验证和自动令牌刷新功能的管理 API SDK 实例。

¥Creates a Management API SDK instance with OAuth authentication and automatic token refresh.

参数:

¥Parameters:

type ManagementApiClientConfig = {
// Required
clientId: string // OAuth client ID
redirectUri: string // OAuth redirect URI
tokenStorage: TokenStorage

// Optional (with defaults)
apiBaseUrl?: string // Default: 'https://api.prisma.io'
authBaseUrl?: string // Default: 'https://auth.prisma.io'
}

返回值:包含以下内容的对象:

¥Returns: An object with:

  • client - 用于发出请求的类型化 API 客户端

    ¥client - The typed API client for making requests

  • getLoginUrl(options) - 生成具有指定范围的 OAuth 登录 URL

    ¥getLoginUrl(options) - Generate OAuth login URL with specified scope

  • handleCallback(options) - 通过 tokenStorage 处理 OAuth 回调并存储令牌

    ¥handleCallback(options) - Handle OAuth callback and store tokens via tokenStorage

  • logout() - 清除已存储的令牌

    ¥logout() - Clear stored tokens

错误处理

¥Error handling

SDK 导出两个错误类:

¥The SDK exports two error classes:

AuthError

因身份验证相关错误抛出:

¥Thrown for authentication-related errors:

  • OAuth 回调错误(如果可用,则包含 error_description

    ¥OAuth callback errors (includes error_description when available)

  • 无效或缺失的令牌

    ¥Invalid or missing tokens

  • 令牌刷新失败

    ¥Token refresh failures

import { AuthError } from '@prisma/management-api-sdk'

try {
await api.handleCallback({ callbackUrl, verifier, expectedState })
} catch (error) {
if (error instanceof AuthError) {
if (error.refreshTokenInvalid) {
// Token is invalid/expired, user needs to log in again
const { url } = await api.getLoginUrl({ scope: 'workspace:admin offline_access' })
// redirect to url...
} else {
// Other auth errors (e.g., "access_denied: User cancelled")
console.error('Auth error:', error.message)
}
}
}

FetchError

因网络相关错误抛出。包含原始错误作为 cause 以便调试:

¥Thrown for network-related errors. Includes the original error as cause for debugging:

import { FetchError } from '@prisma/management-api-sdk'

try {
const { data } = await client.GET('/v1/workspaces')
} catch (error) {
if (error instanceof FetchError) {
console.error('Network error:', error.message)
console.error('Cause:', error.cause) // Original error for debugging
}
}

TypeScript 类型

¥TypeScript types

SDK 导出所有根据 OpenAPI 规范生成的 API 类型:

¥The SDK exports all API types generated from the OpenAPI spec:

import type { paths, components } from '@prisma/management-api-sdk'

// Access response types
type Workspace = components['schemas']['Workspace']
type Project = components['schemas']['Project']