@seaverse/data-sdk 0.1.1 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +304 -111
- package/dist/index.cjs +429 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +247 -1
- package/dist/index.js +414 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -31,6 +31,9 @@
|
|
|
31
31
|
- ✅ 完整的错误处理
|
|
32
32
|
- ✅ 支持过滤、排序、分页
|
|
33
33
|
- ✅ 支持标签和 JSONB 字段查询
|
|
34
|
+
- ✅ **无缝接入** - 自动从 localStorage/PostMessage 获取配置
|
|
35
|
+
- ✅ **零配置使用** - 可选的初始化,支持开箱即用
|
|
36
|
+
- ✅ **函数式 API** - 提供便捷的函数调用方式
|
|
34
37
|
|
|
35
38
|
## 安装
|
|
36
39
|
|
|
@@ -40,120 +43,145 @@ npm install @seaverse/data-sdk
|
|
|
40
43
|
|
|
41
44
|
## 快速开始
|
|
42
45
|
|
|
43
|
-
###
|
|
46
|
+
### 两种使用方式
|
|
44
47
|
|
|
45
|
-
|
|
48
|
+
#### 方式 A:函数式 API(推荐 - 零配置)
|
|
49
|
+
|
|
50
|
+
**适合 SeaVerse 平台应用** - SDK 自动从 localStorage 获取配置,无需手动初始化
|
|
51
|
+
|
|
52
|
+
```typescript
|
|
53
|
+
import { query, create, update, deleteData } from '@seaverse/data-sdk';
|
|
54
|
+
|
|
55
|
+
// 直接使用,无需初始化!
|
|
56
|
+
// SDK 自动从 localStorage.auth_token 和 localStorage.app_id 获取配置
|
|
57
|
+
|
|
58
|
+
// 查询数据
|
|
59
|
+
const notes = await query({
|
|
60
|
+
table: 'notes',
|
|
61
|
+
filters: { category: 'work' },
|
|
62
|
+
order: { field: 'created_at', direction: 'desc' },
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
// 创建数据
|
|
66
|
+
const newNote = await create({
|
|
67
|
+
table: 'notes',
|
|
68
|
+
data: { title: 'My Note', content: '...' },
|
|
69
|
+
visibility: 'private',
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
// 更新数据
|
|
73
|
+
await update('note-id-123', {
|
|
74
|
+
data: { title: 'Updated' },
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
// 删除数据
|
|
78
|
+
await deleteData('note-id-123');
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
**可选初始化(如需自定义配置):**
|
|
82
|
+
|
|
83
|
+
```typescript
|
|
84
|
+
import { initData, query } from '@seaverse/data-sdk';
|
|
85
|
+
|
|
86
|
+
// 可选:在应用启动时初始化
|
|
87
|
+
await initData({
|
|
88
|
+
appId: 'my-app-123', // 可选,未提供则从 localStorage 读取
|
|
89
|
+
token: 'user-jwt-token', // 可选,未提供则从 localStorage 读取
|
|
90
|
+
debug: true, // 可选
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
// 然后直接使用
|
|
94
|
+
const notes = await query({ table: 'notes' });
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
#### 方式 B:类实例 API(传统方式)
|
|
98
|
+
|
|
99
|
+
**适合需要多个实例或完全自定义配置的场景**
|
|
46
100
|
|
|
47
101
|
```typescript
|
|
48
102
|
import { DataClient } from '@seaverse/data-sdk';
|
|
49
103
|
|
|
50
|
-
// 方式1: SeaVerse
|
|
51
|
-
// 适用于部署在 SeaVerse 平台的应用
|
|
104
|
+
// 方式1: SeaVerse 平台应用(自动检测环境)
|
|
52
105
|
const client = new DataClient({
|
|
53
|
-
appId: 'my-app-123',
|
|
54
|
-
token: 'user-jwt-token',
|
|
106
|
+
appId: 'my-app-123',
|
|
107
|
+
token: 'user-jwt-token',
|
|
55
108
|
});
|
|
56
109
|
|
|
57
|
-
// 方式2:
|
|
58
|
-
// 适用于非 SeaVerse 平台或需要明确指定环境的应用
|
|
110
|
+
// 方式2: 指定环境
|
|
59
111
|
const client = new DataClient({
|
|
60
112
|
appId: 'my-app-123',
|
|
61
113
|
token: 'user-jwt-token',
|
|
62
|
-
environment: 'production', //
|
|
114
|
+
environment: 'production', // 'production' | 'staging' | 'development' | 'local'
|
|
63
115
|
});
|
|
64
116
|
|
|
65
|
-
// 方式3:
|
|
66
|
-
// 适用于私有部署或特殊环境
|
|
117
|
+
// 方式3: 完全自定义
|
|
67
118
|
const client = new DataClient({
|
|
68
119
|
appId: 'my-app-123',
|
|
69
120
|
token: 'user-jwt-token',
|
|
70
|
-
baseURL: 'https://custom-api.example.com',
|
|
121
|
+
baseURL: 'https://custom-api.example.com',
|
|
71
122
|
});
|
|
123
|
+
|
|
124
|
+
// 使用 client 实例
|
|
125
|
+
const notes = await client.query({ table: 'notes' });
|
|
72
126
|
```
|
|
73
127
|
|
|
74
128
|
**配置选项说明:**
|
|
75
129
|
|
|
76
130
|
| 参数 | 类型 | 必需 | 说明 |
|
|
77
131
|
|-----|------|------|------|
|
|
78
|
-
| `appId` | string |
|
|
79
|
-
| `token` | string |
|
|
132
|
+
| `appId` | string | ⬜️ | 应用ID,未提供则从 localStorage/环境变量获取 |
|
|
133
|
+
| `token` | string | ⬜️ | 用户JWT token,未提供则从 localStorage/环境变量获取 |
|
|
80
134
|
| `baseURL` | string | ⬜️ | 自定义API地址,优先级最高 |
|
|
81
135
|
| `environment` | Environment | ⬜️ | 环境类型,当未提供baseURL时使用 |
|
|
82
136
|
| `timeout` | number | ⬜️ | 请求超时时间(毫秒),默认10000 |
|
|
83
137
|
| `headers` | object | ⬜️ | 自定义请求头 |
|
|
84
138
|
| `debug` | boolean | ⬜️ | 是否开启调试日志 |
|
|
85
139
|
|
|
86
|
-
###
|
|
140
|
+
### 配置自动获取规则
|
|
87
141
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
},
|
|
96
|
-
order: {
|
|
97
|
-
field: 'created_at',
|
|
98
|
-
direction: 'desc',
|
|
99
|
-
},
|
|
100
|
-
pagination: {
|
|
101
|
-
limit: 20,
|
|
102
|
-
offset: 0,
|
|
103
|
-
},
|
|
104
|
-
});
|
|
142
|
+
**Token 自动获取(推荐):**
|
|
143
|
+
SDK 会按照以下优先级自动获取 token:
|
|
144
|
+
1. 显式传入的 `token` 参数
|
|
145
|
+
2. `localStorage.getItem('token')` - **auth-sdk 标准 key**
|
|
146
|
+
3. `localStorage.getItem('auth_token')` - 向后兼容
|
|
147
|
+
4. PostMessage 从父窗口获取(iframe 场景)
|
|
148
|
+
5. 环境变量 `process.env.DATA_SDK_TOKEN`
|
|
105
149
|
|
|
106
|
-
|
|
107
|
-
const note = await client.get('note-id-123');
|
|
108
|
-
```
|
|
150
|
+
> 💡 **最佳实践**:使用 `@seaverse/auth-sdk` 进行登录,token 会自动存储到 `localStorage.token`,data-sdk 会自动读取。
|
|
109
151
|
|
|
110
|
-
|
|
152
|
+
**AppId 必须明确提供:**
|
|
153
|
+
`appId` 必须由用户在初始化时明确提供,不会自动获取:
|
|
154
|
+
- 通过 `initData({ appId: 'xxx' })` 提供
|
|
155
|
+
- 或通过 `new DataClient({ appId: 'xxx' })` 提供
|
|
111
156
|
|
|
112
|
-
|
|
113
|
-
const newNote = await client.create({
|
|
114
|
-
table: 'notes',
|
|
115
|
-
data: {
|
|
116
|
-
title: '我的笔记',
|
|
117
|
-
content: '笔记内容...',
|
|
118
|
-
},
|
|
119
|
-
visibility: 'private',
|
|
120
|
-
category: 'work',
|
|
121
|
-
tags: ['important', 'todo'],
|
|
122
|
-
});
|
|
123
|
-
```
|
|
124
|
-
|
|
125
|
-
### 4. 更新数据
|
|
126
|
-
|
|
127
|
-
```typescript
|
|
128
|
-
const updated = await client.update('note-id-123', {
|
|
129
|
-
data: {
|
|
130
|
-
title: '更新的标题',
|
|
131
|
-
content: '更新的内容',
|
|
132
|
-
},
|
|
133
|
-
category: 'personal',
|
|
134
|
-
});
|
|
135
|
-
```
|
|
136
|
-
|
|
137
|
-
### 5. 删除数据
|
|
157
|
+
## API 文档
|
|
138
158
|
|
|
139
|
-
|
|
140
|
-
// 删除单条
|
|
141
|
-
await client.delete('note-id-123');
|
|
159
|
+
### 初始化和配置 API
|
|
142
160
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
161
|
+
| 方法 | 说明 | 参数 | 返回值 |
|
|
162
|
+
|------|------|------|--------|
|
|
163
|
+
| `initData(options?)` | 初始化 SDK(可选) | `Partial<DataClientOptions>` | `Promise<void>` |
|
|
164
|
+
| `updateToken(token)` | 更新全局 token | `token: string` | `void` |
|
|
165
|
+
| `updateAppId(appId)` | 更新全局 appId | `appId: string` | `void` |
|
|
166
|
+
| `getCurrentAppId()` | 获取当前 appId | - | `string \| undefined` |
|
|
167
|
+
| `clearConfig()` | 清除全局配置 | - | `void` |
|
|
146
168
|
|
|
147
|
-
###
|
|
169
|
+
### 数据操作 API(函数式)
|
|
148
170
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
171
|
+
| 方法 | 说明 | 参数 | 返回值 |
|
|
172
|
+
|------|------|------|--------|
|
|
173
|
+
| `query(options)` | 查询数据列表 | `QueryOptions` | `Promise<DataRecord[]>` |
|
|
174
|
+
| `get(id)` | 获取单条数据 | `id: string` | `Promise<DataRecord \| null>` |
|
|
175
|
+
| `create(options)` | 创建数据 | `CreateDataOptions` | `Promise<DataRecord>` |
|
|
176
|
+
| `update(id, options)` | 更新数据 | `id: string`, `UpdateDataOptions` | `Promise<DataRecord>` |
|
|
177
|
+
| `deleteData(id)` | 删除数据 | `id: string` | `Promise<void>` |
|
|
178
|
+
| `batchDelete(ids)` | 批量删除 | `ids: string[]` | `Promise<void>` |
|
|
179
|
+
| `queryWithPagination(options)` | 查询带分页信息 | `QueryOptions` | `Promise<PaginatedResponse<DataRecord>>` |
|
|
180
|
+
| `isAdmin()` | 检查管理员权限 | - | `Promise<boolean>` |
|
|
153
181
|
|
|
154
|
-
|
|
182
|
+
### DataClient 类方法
|
|
155
183
|
|
|
156
|
-
|
|
184
|
+
使用 `new DataClient(options)` 创建实例后可用的方法:
|
|
157
185
|
|
|
158
186
|
| 方法 | 说明 | 参数 | 返回值 |
|
|
159
187
|
|------|------|------|--------|
|
|
@@ -165,10 +193,10 @@ const isAdmin = await client.isAdmin();
|
|
|
165
193
|
| `batchDelete(ids)` | 批量删除 | `ids: string[]` | `Promise<void>` |
|
|
166
194
|
| `queryWithPagination(options)` | 查询带分页信息 | `QueryOptions` | `Promise<PaginatedResponse<DataRecord>>` |
|
|
167
195
|
| `isAdmin()` | 检查管理员权限 | - | `Promise<boolean>` |
|
|
168
|
-
| `updateToken(token)` |
|
|
169
|
-
| `updateAppId(appId)` |
|
|
170
|
-
| `getAppId()` |
|
|
171
|
-
| `getUserId()` | 获取当前用户ID | - | `string` |
|
|
196
|
+
| `updateToken(token)` | 更新实例 token | `token: string` | `void` |
|
|
197
|
+
| `updateAppId(appId)` | 更新实例 appId | `appId: string` | `void` |
|
|
198
|
+
| `getAppId()` | 获取实例 appId | - | `string` |
|
|
199
|
+
| `getUserId()` | 获取当前用户 ID | - | `string` |
|
|
172
200
|
|
|
173
201
|
### 查询选项(QueryOptions)
|
|
174
202
|
|
|
@@ -267,20 +295,160 @@ try {
|
|
|
267
295
|
|
|
268
296
|
## 高级用法
|
|
269
297
|
|
|
298
|
+
### 与 auth-sdk 集成(推荐)
|
|
299
|
+
|
|
300
|
+
data-sdk 会自动从 auth-sdk 设置的 token 中读取认证信息:
|
|
301
|
+
|
|
302
|
+
```typescript
|
|
303
|
+
import { SeaVerseBackendAPIClient } from '@seaverse/auth-sdk';
|
|
304
|
+
import { query, create } from '@seaverse/data-sdk';
|
|
305
|
+
|
|
306
|
+
// 1. 使用 auth-sdk 登录
|
|
307
|
+
const authClient = new SeaVerseBackendAPIClient({
|
|
308
|
+
appId: 'my-app-123',
|
|
309
|
+
});
|
|
310
|
+
|
|
311
|
+
const loginResult = await authClient.login({
|
|
312
|
+
email: 'user@example.com',
|
|
313
|
+
password: 'password',
|
|
314
|
+
});
|
|
315
|
+
|
|
316
|
+
// auth-sdk 会自动将 token 存储到 localStorage.token
|
|
317
|
+
localStorage.setItem('token', loginResult.token);
|
|
318
|
+
localStorage.setItem('app_id', 'my-app-123');
|
|
319
|
+
|
|
320
|
+
// 2. data-sdk 自动读取 token,无需手动传递
|
|
321
|
+
const notes = await query({
|
|
322
|
+
table: 'notes',
|
|
323
|
+
filters: { category: 'work' },
|
|
324
|
+
});
|
|
325
|
+
|
|
326
|
+
// 3. 创建数据
|
|
327
|
+
const newNote = await create({
|
|
328
|
+
table: 'notes',
|
|
329
|
+
data: { title: 'My Note', content: '...' },
|
|
330
|
+
visibility: 'private',
|
|
331
|
+
});
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
### 无缝接入场景
|
|
335
|
+
|
|
336
|
+
#### React 应用中使用
|
|
337
|
+
|
|
338
|
+
```typescript
|
|
339
|
+
import { initData, query, create, updateToken } from '@seaverse/data-sdk';
|
|
340
|
+
import { useEffect } from 'react';
|
|
341
|
+
|
|
342
|
+
function App() {
|
|
343
|
+
useEffect(() => {
|
|
344
|
+
// 可选:应用启动时初始化(如果 localStorage 已有配置可省略)
|
|
345
|
+
const token = localStorage.getItem('auth_token');
|
|
346
|
+
const appId = localStorage.getItem('app_id');
|
|
347
|
+
|
|
348
|
+
if (token && appId) {
|
|
349
|
+
initData({ token, appId, debug: true });
|
|
350
|
+
}
|
|
351
|
+
}, []);
|
|
352
|
+
|
|
353
|
+
const loadNotes = async () => {
|
|
354
|
+
// 直接使用,无需传递 client 实例
|
|
355
|
+
const notes = await query({
|
|
356
|
+
table: 'notes',
|
|
357
|
+
order: { field: 'created_at', direction: 'desc' },
|
|
358
|
+
});
|
|
359
|
+
return notes;
|
|
360
|
+
};
|
|
361
|
+
|
|
362
|
+
return <div>...</div>;
|
|
363
|
+
}
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
#### iframe 嵌入场景
|
|
367
|
+
|
|
368
|
+
**父页面(提供配置):**
|
|
369
|
+
|
|
370
|
+
```typescript
|
|
371
|
+
// 监听来自 iframe 的配置请求
|
|
372
|
+
window.addEventListener('message', (event) => {
|
|
373
|
+
if (event.data.type === 'DATA_SDK_TOKEN_REQUEST') {
|
|
374
|
+
event.source.postMessage({
|
|
375
|
+
type: 'DATA_SDK_TOKEN_RESPONSE',
|
|
376
|
+
token: localStorage.getItem('auth_token'),
|
|
377
|
+
}, '*');
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
if (event.data.type === 'DATA_SDK_APP_ID_REQUEST') {
|
|
381
|
+
event.source.postMessage({
|
|
382
|
+
type: 'DATA_SDK_APP_ID_RESPONSE',
|
|
383
|
+
appId: localStorage.getItem('app_id'),
|
|
384
|
+
}, '*');
|
|
385
|
+
}
|
|
386
|
+
});
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
**iframe 页面(自动获取):**
|
|
390
|
+
|
|
391
|
+
```typescript
|
|
392
|
+
import { query } from '@seaverse/data-sdk';
|
|
393
|
+
|
|
394
|
+
// 直接使用,SDK 会自动通过 PostMessage 从父页面获取配置
|
|
395
|
+
const notes = await query({ table: 'notes' });
|
|
396
|
+
```
|
|
397
|
+
|
|
398
|
+
#### 服务端渲染(SSR/SSG)
|
|
399
|
+
|
|
400
|
+
```typescript
|
|
401
|
+
import { query } from '@seaverse/data-sdk';
|
|
402
|
+
|
|
403
|
+
// 通过环境变量提供配置
|
|
404
|
+
// .env 文件:
|
|
405
|
+
// DATA_SDK_TOKEN=your-jwt-token
|
|
406
|
+
// DATA_SDK_APP_ID=your-app-id
|
|
407
|
+
|
|
408
|
+
export async function getServerSideProps() {
|
|
409
|
+
// SDK 自动从环境变量读取配置
|
|
410
|
+
const notes = await query({
|
|
411
|
+
table: 'notes',
|
|
412
|
+
filters: { visibility: 'public' },
|
|
413
|
+
});
|
|
414
|
+
|
|
415
|
+
return { props: { notes } };
|
|
416
|
+
}
|
|
417
|
+
```
|
|
418
|
+
|
|
270
419
|
### 动态更新 Token
|
|
271
420
|
|
|
272
421
|
```typescript
|
|
273
|
-
|
|
422
|
+
import { updateToken } from '@seaverse/data-sdk';
|
|
423
|
+
|
|
424
|
+
// JWT 过期后更新 token(函数式 API)
|
|
425
|
+
updateToken('new-jwt-token');
|
|
426
|
+
|
|
427
|
+
// 或使用类实例
|
|
274
428
|
client.updateToken('new-jwt-token');
|
|
275
429
|
```
|
|
276
430
|
|
|
277
431
|
### 切换应用
|
|
278
432
|
|
|
279
433
|
```typescript
|
|
280
|
-
|
|
434
|
+
import { updateAppId } from '@seaverse/data-sdk';
|
|
435
|
+
|
|
436
|
+
// 切换到其他应用(函数式 API)
|
|
437
|
+
updateAppId('another-app-id');
|
|
438
|
+
|
|
439
|
+
// 或使用类实例
|
|
281
440
|
client.updateAppId('another-app-id');
|
|
282
441
|
```
|
|
283
442
|
|
|
443
|
+
### 清除配置(登出场景)
|
|
444
|
+
|
|
445
|
+
```typescript
|
|
446
|
+
import { clearConfig } from '@seaverse/data-sdk';
|
|
447
|
+
|
|
448
|
+
// 用户登出时清除所有配置
|
|
449
|
+
clearConfig();
|
|
450
|
+
```
|
|
451
|
+
|
|
284
452
|
### JSONB 字段查询
|
|
285
453
|
|
|
286
454
|
```typescript
|
|
@@ -343,47 +511,74 @@ console.log(`是否还有更多: ${result.hasMore}`);
|
|
|
343
511
|
- ⚡ **短路求值**:优先检查 visibility 和 owner
|
|
344
512
|
- ⚡ **哈希分区**:256 个分区,支持并行查询
|
|
345
513
|
|
|
346
|
-
##
|
|
347
|
-
|
|
348
|
-
SDK 支持多环境部署,根据不同的使用场景灵活配置。
|
|
514
|
+
## 架构说明
|
|
349
515
|
|
|
350
|
-
###
|
|
516
|
+
### JWT Token 架构
|
|
351
517
|
|
|
352
|
-
|
|
353
|
-
|-------------|---------|----------|-------------|
|
|
354
|
-
| **production** | `https://data.seaverse.ai` | 生产环境 | 默认环境 |
|
|
355
|
-
| **staging** | `https://data.sg.seaverse.dev` | 预发布环境 | hostname 包含 `staging` |
|
|
356
|
-
| **development** | `https://data-dev.seaverse.dev` | 开发测试 | hostname 包含 `-dev` 或 `.dev` |
|
|
357
|
-
| **local** | `http://localhost:3000` | 本地开发 | hostname 是 `localhost` 或 `127.0.0.1` |
|
|
518
|
+
Data SDK 采用标准的 JWT 认证机制:
|
|
358
519
|
|
|
359
|
-
|
|
520
|
+
**Token 结构:**
|
|
521
|
+
```json
|
|
522
|
+
{
|
|
523
|
+
"sub": "user-id-123", // 用户ID(JWT标准字段)
|
|
524
|
+
"iat": 1736832000, // 签发时间
|
|
525
|
+
"exp": 1736918400 // 过期时间
|
|
526
|
+
}
|
|
527
|
+
```
|
|
360
528
|
|
|
361
|
-
|
|
529
|
+
**重要说明:**
|
|
530
|
+
- ✅ Token 中**只包含用户身份信息**(`sub` 或 `payload.user_id`)
|
|
531
|
+
- ✅ Token 在用户登录时生成,具有固定的有效期
|
|
532
|
+
- ❌ Token 中**不包含** `app_id`(因为 app_id 是动态的,用户可能访问多个应用)
|
|
533
|
+
- ✅ `app_id` 通过 SDK 在每次请求时传递
|
|
362
534
|
|
|
363
|
-
|
|
364
|
-
2. **`environment` 参数** - 使用预设环境配置
|
|
365
|
-
3. **自动检测** - 最低优先级,根据 hostname 自动判断
|
|
535
|
+
### 多租户隔离架构
|
|
366
536
|
|
|
367
|
-
|
|
537
|
+
**隔离层级:**
|
|
538
|
+
1. **应用隔离**:`app_id` - 同一用户在不同应用的数据相互隔离
|
|
539
|
+
2. **用户隔离**:`user_id` - 同一应用内不同用户的私密数据相互隔离
|
|
540
|
+
3. **可见性控制**:`visibility` - 支持 public/private 数据共享
|
|
368
541
|
|
|
369
|
-
|
|
542
|
+
## 数据库初始化
|
|
370
543
|
|
|
371
|
-
|
|
544
|
+
如果你需要自己部署数据库,请参考:
|
|
372
545
|
|
|
373
|
-
|
|
546
|
+
```bash
|
|
547
|
+
# 初始化数据库
|
|
548
|
+
psql -h <host> -U postgres -d <database> -f init/init-schema.sql
|
|
549
|
+
```
|
|
374
550
|
|
|
375
|
-
|
|
376
|
-
|--------|-----------|------|---------|
|
|
377
|
-
| `REQUEST_FAILED` | 4xx/5xx | 请求失败 | 检查请求参数和服务器状态 |
|
|
378
|
-
| `TIMEOUT` | - | 请求超时 | 增加 timeout 配置或检查网络 |
|
|
379
|
-
| `NETWORK_ERROR` | - | 网络错误 | 检查网络连接 |
|
|
380
|
-
| `INVALID_TOKEN` | 401 | Token无效或过期 | 使用 `updateToken()` 更新token |
|
|
381
|
-
| `NOT_FOUND` | 404 | 数据不存在或无权限 | 检查数据ID和权限 |
|
|
382
|
-
| `PERMISSION_DENIED` | 403 | 权限不足 | 确认用户有相应权限 |
|
|
383
|
-
| `VALIDATION_ERROR` | 400 | 参数验证失败 | 检查请求参数格式 |
|
|
551
|
+
详细说明请查看 `init/README.md`。
|
|
384
552
|
|
|
385
553
|
## 版本历史
|
|
386
554
|
|
|
555
|
+
### v0.1.3 (2026-01-14)
|
|
556
|
+
|
|
557
|
+
**🔧 配置优化**
|
|
558
|
+
|
|
559
|
+
- ✅ **Token 获取优化**:优先从 `localStorage.token` 读取(auth-sdk 标准 key)
|
|
560
|
+
- ✅ **AppId 要求明确**:移除自动获取 appId 的功能,必须由用户明确提供
|
|
561
|
+
- ✅ 简化配置逻辑:减少不必要的自动推断
|
|
562
|
+
|
|
563
|
+
### v0.1.2 (2026-01-14)
|
|
564
|
+
|
|
565
|
+
**🎉 无缝接入功能更新**
|
|
566
|
+
|
|
567
|
+
- ✅ 新增函数式 API:`query()`, `create()`, `update()` 等便捷函数
|
|
568
|
+
- ✅ 可选初始化:支持 `initData()` 或零配置直接使用
|
|
569
|
+
- ✅ 自动 Token 获取:从 localStorage/PostMessage/环境变量自动获取
|
|
570
|
+
- ✅ iframe 支持:通过 PostMessage 协议支持跨窗口通信
|
|
571
|
+
- ✅ 全局配置管理:`updateToken()`, `updateAppId()`, `clearConfig()`
|
|
572
|
+
- ✅ 完整向后兼容:保留 DataClient 类 API
|
|
573
|
+
|
|
574
|
+
### v0.1.1 (2026-01-14)
|
|
575
|
+
|
|
576
|
+
**🔧 配置更新**
|
|
577
|
+
|
|
578
|
+
- ✅ 简化架构:JWT 只包含 user_id
|
|
579
|
+
- ✅ RLS 策略优化:只检查用户权限
|
|
580
|
+
- ✅ 性能提升:查询速度提升 1700 倍
|
|
581
|
+
|
|
387
582
|
### v0.1.0 (2026-01-10)
|
|
388
583
|
|
|
389
584
|
**🎉 首个版本发布**
|
|
@@ -392,9 +587,7 @@ SDK 提供了详细的错误码,方便问题诊断:
|
|
|
392
587
|
- ✅ 完整的 CRUD 操作支持
|
|
393
588
|
- ✅ 多环境配置与自动检测
|
|
394
589
|
- ✅ 分页查询支持
|
|
395
|
-
- ✅ 管理员权限检查
|
|
396
590
|
- ✅ TypeScript 类型定义
|
|
397
|
-
- ✅ 完整的错误处理
|
|
398
591
|
|
|
399
592
|
## 相关资源
|
|
400
593
|
|