@amaster.ai/client
v1.1.1
Published
Unified API client for Amaster platform - All services in one package
Readme
@amaster.ai/client
Unified API client for the Amaster platform - All services in one package
🤖 AI-Friendly Documentation
This package is designed with AI tools (GitHub Copilot, Cursor, etc.) in mind:
- Modular Type Definitions: API documentation split into focused modules
- Rich JSDoc: Every method includes detailed descriptions and examples
- On-Demand Loading: AI tools only load relevant type files when needed
- Type-Driven Learning: Full TypeScript support helps AI understand API patterns
Type Documentation Structure
types/
├── index.d.ts # Main entry (lightweight)
├── auth/ # Authentication (split into 7 focused modules)
│ ├── user.d.ts
│ ├── password-auth.d.ts
│ ├── code-auth.d.ts
│ ├── oauth.d.ts
│ ├── permissions.d.ts
│ ├── profile.d.ts
│ └── index.d.ts
├── entity.d.ts # Entity CRUD operations
├── bpm.d.ts # Business Process Management
├── workflow.d.ts # Workflow execution
├── asr.d.ts # Speech Recognition (WebSocket)
├── copilot.d.ts # AI Assistant / Chat
├── function.d.ts # Function invocation
└── tts.d.ts # Text-to-Speech (WebSocket)Each module contains:
- Complete method signatures
- Parameter descriptions
- Return type definitions
- Multiple usage examples
- Best practices
🚀 Overview
@amaster.ai/client is a unified JavaScript/TypeScript client that provides a simple, consistent interface to all Amaster platform services. Inspired by Supabase's elegant API design, it offers:
✨ Single client instance for all services
🔐 Automatic authentication - tokens attached to all requests
🔄 Token auto-refresh - never worry about expiration
📦 Type-safe - Full TypeScript support with auto-completion
🎯 Simple API - Clean, consistent method naming
🌐 Complete Integration - Auth, Entity, BPM, Workflow, ASR, Copilot, Function, TTS, S3
📦 Installation
# npm
npm install @amaster.ai/client axios
# pnpm
pnpm add @amaster.ai/client axios
# yarn
yarn add @amaster.ai/client axios🎯 Quick Start
import { createClient } from "@amaster.ai/client";
// 1. Create client instance (baseURL is optional)
const client = createClient({
baseURL: "https://api.amaster.ai", // Optional - auto-detects from env in Taro/Mini-program
onUnauthorized: () => {
// Handle unauthorized (redirect to login, show modal, etc.)
window.location.href = "/login";
},
});
// Or simply:
// const client = createClient({}); // Auto-uses VITE_API_BASE_URL or dev proxy
// 2. Login
await client.auth.login({
email: "[email protected]",
password: "password123",
});
// 3. Use any service - auth token is automatically attached!
const users = await client.entity.list("default", "users");
const tasks = await client.bpm.getMyTasks();
const result = await client.workflow.execute("my-workflow", { input: {} });🔑 Authentication
Login
// Email/Password login
const result = await client.auth.login({
email: "[email protected]",
password: "password123",
});
if (result.success) {
console.log("Logged in:", result.data.user);
}Register
const result = await client.auth.register({
username: "johndoe",
email: "[email protected]",
password: "securePassword123",
});Get Current User
const result = await client.auth.getMe();
if (result.success) {
console.log("Current user:", result.data);
}Logout
await client.auth.logout();Check Authentication Status
if (client.isAuthenticated()) {
console.log("User is logged in");
}📊 Entity Operations (CRUD)
Full CRUD operations for your data entities with type safety.
List Entities
const result = await client.entity.list("default", "users", {
page: 1,
perPage: 20,
orderBy: "createdAt",
orderDir: "desc",
// Filters
"status[eq]": "active",
"age[gt]": 18,
});
if (result.success) {
const { items, total, page, perPage } = result.data;
console.log(`Found ${total} users`);
}Get Single Entity
const result = await client.entity.get("default", "users", 123);
if (result.success) {
console.log("User:", result.data);
}Create Entity
const result = await client.entity.create("default", "users", {
name: "John Doe",
email: "[email protected]",
status: "active",
});Update Entity
const result = await client.entity.update("default", "users", 123, {
name: "Jane Doe",
status: "inactive",
});Delete Entity
await client.entity.delete("default", "users", 123);Bulk Operations
// Bulk update
await client.entity.bulkUpdate("default", "users", [
{ id: 1, status: "active" },
{ id: 2, status: "inactive" },
]);
// Bulk delete
await client.entity.bulkDelete("default", "users", [1, 2, 3]);🔄 BPM (Business Process Management)
Manage business processes powered by Camunda 7.
Start a Process
const result = await client.bpm.startProcess({
processKey: "approval-process",
businessKey: "ORDER-12345",
variables: {
amount: 1000,
requester: "[email protected]",
},
});Get My Tasks
const result = await client.bpm.getMyTasks({
page: 1,
perPage: 20,
sortBy: "created",
sortOrder: "desc",
});
if (result.success) {
console.log("Tasks:", result.data.items);
}Complete a Task
await client.bpm.completeTask("task-id", {
approved: true,
comments: "Looks good!",
});Claim a Task
await client.bpm.claimTask("task-id");⚡ Workflow Execution
Execute workflows and automation flows.
const result = await client.workflow.execute("data-processing-workflow", {
input: {
dataSource: "users",
filters: { status: "active" },
},
});
if (result.success) {
console.log("Workflow result:", result.data);
}🎙️ ASR (Automatic Speech Recognition)
实时语音识别支持 WebSocket 流式识别和 HTTP 按压识别两种方式。
WebSocket ASR(实时流式识别)
适合需要实时看到识别结果的场景,如语音输入、实时字幕等。
import { useRef, useState } from "react";
import type { ASRClient } from "@amaster.ai/client";
function ASRRealtimeDemo() {
const asrRef = useRef<ASRClient | null>(null);
const [result, setResult] = useState("");
const [status, setStatus] = useState("idle"); // idle | connecting | ready | error | closed
const start = async () => {
let finalResult = "";
let temp = "";
setStatus("connecting");
const asrClient = client.asr({
onReady() {
setStatus("ready");
},
onTranscript(text, isFinal) {
if (!isFinal) {
temp = text;
setResult(finalResult + temp);
} else {
temp = "";
finalResult += text;
setResult(finalResult);
}
},
onError(err) {
console.error(err);
setStatus("error");
},
onClose() {
setStatus("closed");
},
});
await asrClient.connect();
await asrClient.startRecording();
asrRef.current = asrClient;
};
const stop = () => {
asrRef.current?.stopRecording();
asrRef.current?.close();
asrRef.current = null;
setStatus("idle");
};
return (
<div>
<div>状态: {status}</div>
<button onClick={start} disabled={status === "connecting" || status === "ready"}>
开始录音
</button>
<button onClick={stop} disabled={status !== "ready"}>
停止
</button>
<div>识别结果: {result || "(等待说话...)"}</div>
</div>
);
}HTTP ASR(按压识别)
适合按住说话、松开识别的场景,如语音消息、语音搜索等。
import { useRef, useState } from "react";
import type { ASRHttpClient } from "@amaster.ai/client";
function ASRPressToTalkDemo() {
const clientRef = useRef<ASRHttpClient | null>(null);
const [recording, setRecording] = useState(false);
const [text, setText] = useState("");
const [error, setError] = useState<string | null>(null);
if (!clientRef.current) {
clientRef.current = client.asrHttp({
onRecordingStart() {
setRecording(true);
setText("");
setError(null);
},
onRecordingStop() {
setRecording(false);
},
onResult(result) {
setText(result);
},
onError(err) {
setError(err.message);
},
});
}
const asrHttpClient = clientRef.current;
return (
<div>
<button
onMouseDown={() => asrHttpClient.startRecording()}
onMouseUp={() => asrHttpClient.stopRecording()}
onTouchStart={() => asrHttpClient.startRecording()}
onTouchEnd={() => asrHttpClient.stopRecording()}
style={{
padding: "12px 24px",
background: recording ? "#f87171" : "#4ade80",
}}
>
{recording ? "松开识别" : "按住说话"}
</button>
<div>
<strong>识别结果:</strong>
<div>{text || "(暂无)"}</div>
</div>
{error && <div style={{ color: "red" }}>错误:{error}</div>}
</div>
);
}ASR Client 配置说明:
| 参数 | 类型 | 说明 |
| ------------------ | ------------------------------------------ | ------------------------------ |
| onReady | () => void | 会话创建完成 |
| onSpeechStart | () => void | 检测到语音开始(仅 WebSocket) |
| onSpeechEnd | () => void | 检测到语音结束(仅 WebSocket) |
| onTranscript | (text: string, isFinal: boolean) => void | 转写回调(WebSocket) |
| onRecordingStart | () => void | 录音开始回调(仅 HTTP) |
| onRecordingStop | () => void | 录音停止回调(仅 HTTP) |
| onResult | (text: string) => void | 识别结果回调(HTTP) |
| onError | (error: Error) => void | 错误回调 |
| onClose | () => void | 连接关闭回调(WebSocket) |
🔊 TTS (Text-to-Speech)
WebSocket 实时语音合成。
import { useRef, useState } from "react";
import type { TTSClient } from "@amaster.ai/client";
function TTSDemo() {
const [voice, setVoice] = useState("Cherry");
const [connected, setConnected] = useState(false);
const [status, setStatus] = useState("disconnected");
const [text, setText] = useState("你好,欢迎使用实时语音合成服务。");
const clientRef = useRef<TTSClient | null>(null);
const connectTTS = () => {
if (clientRef.current) return;
const ttsClient = client.tts({
voice,
autoPlay: true,
audioFormat: "pcm",
sampleRate: 24000,
onReady: () => {
setConnected(true);
setStatus("connected");
},
onAudioStart: () => setStatus("playing"),
onAudioEnd: () => setStatus("connected"),
onAudioChunk: (chunks) => {
console.log("收到音频片段:", chunks.length);
},
onError: (err) => {
console.error("TTS Error:", err);
setStatus("error");
},
});
ttsClient.connect();
clientRef.current = ttsClient;
};
const sendTTS = () => {
if (!text || !clientRef.current) return;
clientRef.current.speak(text);
setStatus("sending");
};
const disconnectTTS = () => {
clientRef.current?.close();
clientRef.current = null;
setConnected(false);
setStatus("disconnected");
};
return (
<div>
<h3>🔊 实时语音合成</h3>
<div>状态: {status}</div>
<div>
<label>音色:</label>
<select value={voice} onChange={(e) => setVoice(e.target.value)}>
<option value="Cherry">Cherry - 甜美女声</option>
<option value="Serena">苏瑶 - 温柔小姐姐</option>
<option value="Ethan">晨煦 - 标准普通话</option>
<option value="Chelsie">千雪 - 二次元虚拟女友</option>
<option value="Peter">天津话</option>
</select>
</div>
<div>
<label>合成文本:</label>
<textarea rows={4} value={text} onChange={(e) => setText(e.target.value)} />
</div>
<div>
<button onClick={connectTTS} disabled={connected}>
连接
</button>
<button onClick={sendTTS} disabled={!connected}>
合成语音
</button>
<button onClick={disconnectTTS} disabled={!connected}>
断开
</button>
</div>
</div>
);
}TTS Client 配置说明:
| 参数 | 类型 | 默认值 | 说明 |
| -------------- | ----------------------------------- | ---------- | ------------------------------ |
| voice | string | "Cherry" | 发音人名称 |
| autoPlay | boolean | true | 是否自动播放 |
| audioFormat | "pcm" \| "mp3" \| "wav" \| "opus" | "pcm" | 音频格式(内置播放仅支持 pcm) |
| sampleRate | number | 24000 | 采样率 |
| onReady | () => void | - | 会话就绪回调 |
| onAudioStart | () => void | - | 音频开始播放回调 |
| onAudioEnd | () => void | - | 音频播放结束回调 |
| onAudioChunk | (chunks: string[]) => void | - | 音频分片回调 |
| onError | (error: Error) => void | - | 错误回调 |
🤖 Copilot (AI Assistant)
AI assistant / chatbot API.
// Simple chat
const result = await client.copilot.sendMessage([
{ role: "user", content: "Hello, how can you help?" },
]);
console.log(result.data.content);
// Streaming response
await client.copilot.sendMessage([{ role: "user", content: "Tell me a story" }], {
stream: true,
onChunk: (chunk) => console.log(chunk),
});⚙️ Function Invocation
调用服务端函数。
// Call a function
const result = await client.function.invoke<{ result: string }>("sendEmail", {
to: "[email protected]",
subject: "Hello",
});
if (result.data) {
console.log("Function result:", result.data.result);
}☁️ S3 Storage
文件上传下载。
// Upload file
await client.s3.upload(file);
// Download file
await client.s3.download("path/to/file");⚙️ Configuration
Client Options
interface AmasterClientOptions {
/** Base URL for the Amaster API */
baseURL: string;
/** Optional custom headers */
headers?: Record<string, string>;
/** Called when receiving 401 Unauthorized */
onUnauthorized?: () => void;
/** Called when token expires (before auto-refresh) */
onTokenExpired?: () => void;
/** Enable automatic token refresh (default: true) */
autoRefresh?: boolean;
/** Refresh threshold in seconds (default: 300) */
refreshThreshold?: number;
/** Automatically handle OAuth callback on initialization (default: true) */
autoHandleOAuthCallback?: boolean;
}Example with All Options
const client = createClient({
baseURL: "https://api.amaster.ai",
headers: {
"X-App-Version": "1.0.0",
},
onUnauthorized: () => {
console.log("Session expired, redirecting to login...");
window.location.href = "/login";
},
onTokenExpired: () => {
console.log("Token expired, will auto-refresh");
},
autoRefresh: true,
refreshThreshold: 300, // Refresh 5 minutes before expiry
});🔧 Advanced Usage
Manual Token Management
// Get current access token
const token = client.getAccessToken();
// Set token manually (useful for SSR or external auth)
client.setAccessToken("your-jwt-token");
// Clear all auth data
client.clearAuth();Error Handling
const result = await client.entity.list("default", "users");
if (result.success) {
// Success case
console.log("Data:", result.data);
} else {
// Error case
console.error("Error:", result.error);
console.error("Status:", result.statusCode);
}Custom HTTP Requests
// Make a custom request with automatic auth
const { data, error } = await client.http.request({
url: "/custom/endpoint",
method: "POST",
data: { key: "value" },
});🎨 Comparison with Individual Clients
Before (Using separate clients)
import { createAuthClient } from "@amaster.ai/auth-client";
import { createEntityClient } from "@amaster.ai/entity-client";
import { createBpmClient } from "@amaster.ai/bpm-client";
const authClient = createAuthClient({ baseURL });
const entityClient = createEntityClient({ baseURL });
const bpmClient = createBpmClient({ baseURL });
// Need to manage tokens manually across clients
await authClient.login({ email, password });
const token = authClient.getAccessToken();
// Pass token to other clients somehow...After (Using unified client)
import { createClient } from "@amaster.ai/client";
const client = createClient({ baseURL });
// One client, automatic token management
await client.auth.login({ email, password });
await client.entity.list("default", "users"); // Token automatically attached
await client.bpm.getMyTasks(); // Token automatically attached📖 API Reference
client.auth
Full authentication API from @amaster.ai/auth-client:
login(params)- Email/password or code-based loginregister(params)- User registrationlogout()- User logoutgetMe()- Get current user profileupdateMe(params)- Update current userchangePassword(params)- Change passwordrefreshToken()- Manually refresh tokensendCode(params)- Send verification codehasPermission(permission)- Check user permissionhasRole(role)- Check user role
client.entity
Full CRUD API from @amaster.ai/entity-client:
list(source, entity, params?)- List entities with paginationget(source, entity, id)- Get single entitycreate(source, entity, data)- Create new entityupdate(source, entity, id, data)- Update entitydelete(source, entity, id)- Delete entitybulkUpdate(source, entity, items)- Bulk updatebulkDelete(source, entity, ids)- Bulk deleteoptions(source, entity, fields?)- Get field options
client.bpm
Full BPM API from @amaster.ai/bpm-client:
startProcess(params)- Start process instancegetMyTasks(params?)- Get current user's taskscompleteTask(taskId, variables?)- Complete a taskclaimTask(taskId)- Claim a taskunclaimTask(taskId)- Unclaim a task- And more...
client.workflow
Workflow execution API from @amaster.ai/workflow-client:
execute(workflowId, params)- Execute a workflowgetStatus(executionId)- Get execution status- And more...
client.asr
WebSocket real-time speech recognition:
connect()- Connect to ASR servicestartRecording()- Start microphone recordingstopRecording()- Stop recordingclose()- Close connection
client.asrHttp
HTTP press-to-talk speech recognition:
startRecording()- Start recordingstopRecording()- Stop and get resultrecognizeFile(file)- Recognize audio filerecognizeUrl(url)- Recognize audio URL
client.tts
WebSocket real-time text-to-speech:
connect()- Connect to TTS servicespeak(text)- Synthesize and play speechplay()- Manually play audioclose()- Close connection
client.copilot
AI assistant API:
sendMessage(messages, options?)- Send messages to AI
client.function
Function invocation API:
invoke<T>(funcName, params?)- Invoke a serverless function
client.s3
S3 storage API:
upload(file)- Upload filedownload(path)- Download file
🔐 Token Management Flow
1. Login → Token stored automatically
2. Request → Token attached to headers
3. Response 401 → onUnauthorized() called
4. Token near expiry → Auto-refresh (if enabled)
5. Logout → Token cleared🌐 Environment Support
Works in:
- ✅ Browser (modern)
- ✅ Node.js (18+)
- ✅ React / Vue / Angular
- ✅ Next.js / Nuxt
- ✅ React Native (with axios)
📄 License
MIT © Amaster Team
🤝 Related Packages
All these packages are now integrated into @amaster.ai/client:
@amaster.ai/auth-client- Authentication (login, register, etc.)@amaster.ai/entity-client- Entity CRUD operations@amaster.ai/bpm-client- Business Process Management@amaster.ai/workflow-client- Workflow execution@amaster.ai/asr-client- Speech recognition (WebSocket + HTTP)@amaster.ai/copilot-client- AI assistant / chatbot@amaster.ai/function-client- Function invocation@amaster.ai/tts-client- Text-to-speech (WebSocket)@amaster.ai/s3-client- S3 storage operations@amaster.ai/http-client- HTTP client foundation (internal)
💡 Inspiration
API design inspired by Supabase - aiming for the same level of developer experience and simplicity.
