mall数据库文件
This commit is contained in:
22
components/supadb/docs/CHANGELOG.md
Normal file
22
components/supadb/docs/CHANGELOG.md
Normal file
@@ -0,0 +1,22 @@
|
||||
# SupaDB 文档更新记录
|
||||
|
||||
## 2026-01-30
|
||||
|
||||
### AkSupa:从本地持久化 token 恢复 user/session
|
||||
|
||||
- **文件**:`components/supadb/aksupa.uts`
|
||||
- **位置**:`export class AkSupa` -> `constructor(baseUrl: string, apikey: string)`,以及新增方法 `hydrateSessionFromStorage()`
|
||||
- **定位标记**:在代码中搜索 `// [CHANGE][2026-01-30]`
|
||||
|
||||
#### 修改了什么
|
||||
|
||||
- 在 `AkSupa` 构造时,会尝试基于本地已持久化的 token(由 `AkReq.setToken` 写入 storage)恢复登录态。
|
||||
- 新增 `hydrateSessionFromStorage()`:
|
||||
- 通过 `AkReq.getToken()` 读取本地 access token
|
||||
- 若 token 存在,则请求 `GET {baseUrl}/auth/v1/user`
|
||||
- 将返回的 user 写入 `this.user`
|
||||
- 若 `this.session` 为空,则补齐一个最小 session 对象,使 `getSession()` 在「重启 App / 刷新页面」后仍能正确反映登录状态
|
||||
|
||||
#### 为什么要改
|
||||
|
||||
此前 `AkReq` 会把 token 持久化到本地,但 `AkSupa` 启动时不会自动恢复 `this.user` / `this.session`,导致即使 token 仍有效,`getSession()` 也可能返回 `{ session: null, user: null }`,从而使依赖登录态的页面判断失败。
|
||||
155
components/supadb/docs/SIMPLIFIED_API_GUIDE.md
Normal file
155
components/supadb/docs/SIMPLIFIED_API_GUIDE.md
Normal file
@@ -0,0 +1,155 @@
|
||||
# AkSupa 简化API指南
|
||||
|
||||
## 概述
|
||||
|
||||
AkSupa 现在采用了**简化的单一方法**设计:只提供 `executeAs<T>()` 方法进行类型安全的数据访问,移除了所有冗余的类型转换方法。
|
||||
|
||||
## 重要变化
|
||||
|
||||
### 🚫 已移除的方法
|
||||
- `selectAs<T>()`
|
||||
- `insertAs<T>()`
|
||||
- `updateAs<T>()`
|
||||
- `deleteAs<T>()`
|
||||
- `rpcAs<T>()`
|
||||
|
||||
### ✅ 统一的方法
|
||||
- `executeAs<T>()` - 唯一的类型转换方法
|
||||
|
||||
## 设计理念
|
||||
|
||||
### 简洁性原则
|
||||
- **一个方法解决所有问题**:所有查询操作最终都要调用 `execute()`,`executeAs<T>()` 是其类型安全版本
|
||||
- **减少API复杂性**:不需要记住多个不同的方法名
|
||||
- **保持一致性**:无论是查询、插入、更新还是删除,都使用相同的方法
|
||||
|
||||
### 链式友好
|
||||
```typescript
|
||||
// 所有操作都遵循相同的模式
|
||||
const result = await supa
|
||||
.from('table')
|
||||
.operation() // select(), insert(), update(), delete(), rpc()
|
||||
.conditions() // eq(), gt(), like(), etc.
|
||||
.executeAs<T>(); // 统一的类型转换方法
|
||||
```
|
||||
|
||||
## 使用示例
|
||||
|
||||
### 查询数据
|
||||
```typescript
|
||||
// 多条记录
|
||||
const users = await supa
|
||||
.from('users')
|
||||
.select('*')
|
||||
.eq('status', 'active')
|
||||
.executeAs<User[]>();
|
||||
|
||||
// 单条记录
|
||||
const user = await supa
|
||||
.from('users')
|
||||
.select('*')
|
||||
.eq('id', 1)
|
||||
.single()
|
||||
.executeAs<User>();
|
||||
```
|
||||
|
||||
### 插入数据
|
||||
```typescript
|
||||
const newUser = await supa
|
||||
.from('users')
|
||||
.insert({
|
||||
name: 'John',
|
||||
email: 'john@example.com'
|
||||
})
|
||||
.executeAs<User>();
|
||||
```
|
||||
|
||||
### 更新数据
|
||||
```typescript
|
||||
const updatedUser = await supa
|
||||
.from('users')
|
||||
.update({ name: 'Jane' })
|
||||
.eq('id', 1)
|
||||
.executeAs<User>();
|
||||
```
|
||||
|
||||
### 删除数据
|
||||
```typescript
|
||||
const deletedUser = await supa
|
||||
.from('users')
|
||||
.delete()
|
||||
.eq('id', 1)
|
||||
.executeAs<User>();
|
||||
```
|
||||
|
||||
### RPC调用
|
||||
```typescript
|
||||
const result = await supa
|
||||
.from('any_table')
|
||||
.rpc('my_function', { param1: 'value1' })
|
||||
.executeAs<ResultType>();
|
||||
```
|
||||
|
||||
## 平台兼容性
|
||||
|
||||
| 平台 | 类型转换机制 | 说明 |
|
||||
|------|-------------|------|
|
||||
| Android | `UTSJSONObject.parse<T>()` | 真正的类型转换 |
|
||||
| HarmonyOS | `UTSJSONObject.parse<T>()` | 真正的类型转换 |
|
||||
| Web/iOS | `as T` | 类型断言 |
|
||||
|
||||
## 从旧版本迁移
|
||||
|
||||
### 旧代码
|
||||
```typescript
|
||||
// 旧方式 - 多个方法
|
||||
const users = await supa.selectAs<User[]>('users', null, { limit: 10 });
|
||||
const newUser = await supa.insertAs<User>('users', userData);
|
||||
const updated = await supa.updateAs<User>('users', filter, updateData);
|
||||
```
|
||||
|
||||
### 新代码
|
||||
```typescript
|
||||
// 新方式 - 统一方法
|
||||
const users = await supa
|
||||
.from('users')
|
||||
.select('*')
|
||||
.limit(10)
|
||||
.executeAs<User[]>();
|
||||
|
||||
const newUser = await supa
|
||||
.from('users')
|
||||
.insert(userData)
|
||||
.executeAs<User>();
|
||||
|
||||
const updated = await supa
|
||||
.from('users')
|
||||
.update(updateData)
|
||||
.eq('id', userId)
|
||||
.executeAs<User>();
|
||||
```
|
||||
|
||||
## 优势
|
||||
|
||||
1. **API简洁**:只需要记住一个方法
|
||||
2. **类型安全**:TypeScript 编译时检查
|
||||
3. **平台兼容**:Android/HarmonyOS 使用真正的类型转换
|
||||
4. **链式友好**:与现有的链式方法无缝集成
|
||||
5. **维护性强**:单一方法,减少维护成本
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. **泛型类型**:确保传入正确的类型参数 `<T>`
|
||||
2. **错误处理**:检查 `result.error` 和 `result.data` 的有效性
|
||||
3. **性能考虑**:Android 平台的类型转换有轻微性能开销
|
||||
4. **调试模式**:开发时会有转换过程的控制台输出
|
||||
|
||||
## 总结
|
||||
|
||||
通过采用单一的 `executeAs<T>()` 方法,AkSupa 现在提供了:
|
||||
- 更简洁的API
|
||||
- 更好的类型安全
|
||||
- 更一致的使用体验
|
||||
- 更容易维护的代码
|
||||
|
||||
这个设计遵循了"简单就是美"的原则,让开发者能够更专注于业务逻辑而不是API的复杂性。
|
||||
194
components/supadb/docs/TYPED_QUERIES_README.md
Normal file
194
components/supadb/docs/TYPED_QUERIES_README.md
Normal file
@@ -0,0 +1,194 @@
|
||||
# AkSupa executeAs<T>() 类型转换功能
|
||||
|
||||
## 概述
|
||||
|
||||
AkSupa 现在提供简洁的 `executeAs<T>()` 方法,支持链式请求的类型转换功能,可以直接返回指定的类型而不仅仅是 `UTSJSONObject`。
|
||||
|
||||
## 设计理念
|
||||
|
||||
遵循 **简洁性原则**,只提供一个 `executeAs<T>()` 方法来处理所有类型转换需求,因为:
|
||||
|
||||
1. **统一API**:所有操作最终都通过 `execute()` 处理,`executeAs<T>()` 是其类型安全版本
|
||||
2. **链式友好**:可以与所有现有的链式方法无缝组合
|
||||
3. **易于理解**:只需记住一个方法,降低学习成本
|
||||
4. **功能完整**:覆盖查询、插入、更新、删除、RPC 等所有操作
|
||||
|
||||
## 平台兼容性
|
||||
|
||||
| 平台 | 支持方式 | 说明 |
|
||||
|------|----------|------|
|
||||
| Android (uni-app x 3.90+) | `UTSJSONObject.parse()` | 真正的类型转换 |
|
||||
| Web | `as T` | 类型断言,编译时类型提示 |
|
||||
| iOS | `as T` | 类型断言,编译时类型提示 |
|
||||
| HarmonyOS (4.61+) | `UTSJSONObject.parse()` | 真正的类型转换 |
|
||||
|
||||
## 方法签名
|
||||
|
||||
```typescript
|
||||
async executeAs<T>() : Promise<AkReqResponse<T>>
|
||||
```
|
||||
|
||||
## 使用示例
|
||||
|
||||
### 1. 定义数据类型
|
||||
|
||||
```typescript
|
||||
export type User = {
|
||||
id: number;
|
||||
name: string;
|
||||
email: string;
|
||||
created_at: string;
|
||||
avatar_url?: string;
|
||||
}
|
||||
```
|
||||
|
||||
### 2. 查询操作
|
||||
|
||||
```typescript
|
||||
// 查询多条记录
|
||||
const usersResult = await supa
|
||||
.from('users')
|
||||
.select('*')
|
||||
.eq('status', 'active')
|
||||
.limit(10)
|
||||
.executeAs<User[]>();
|
||||
|
||||
// 查询单条记录
|
||||
const userResult = await supa
|
||||
.from('users')
|
||||
.select('*')
|
||||
.eq('id', 1)
|
||||
.single()
|
||||
.executeAs<User>();
|
||||
|
||||
// 复杂查询
|
||||
const complexQuery = await supa
|
||||
.from('posts')
|
||||
.select('*, users!posts_user_id_fkey(*)')
|
||||
.eq('status', 'published')
|
||||
.gt('created_at', '2024-01-01')
|
||||
.order('created_at', { ascending: false })
|
||||
.limit(20)
|
||||
.executeAs<Post[]>();
|
||||
```
|
||||
|
||||
### 3. 插入操作
|
||||
|
||||
```typescript
|
||||
const newUser = {
|
||||
name: '新用户',
|
||||
email: 'newuser@example.com'
|
||||
} as UTSJSONObject;
|
||||
|
||||
const insertResult = await supa
|
||||
.from('users')
|
||||
.insert(newUser)
|
||||
.executeAs<User[]>();
|
||||
```
|
||||
|
||||
### 4. 更新操作
|
||||
|
||||
```typescript
|
||||
const updateResult = await supa
|
||||
.from('users')
|
||||
.update({ name: '更新的名称' } as UTSJSONObject)
|
||||
.eq('id', 1)
|
||||
.executeAs<User[]>();
|
||||
```
|
||||
|
||||
### 5. 删除操作
|
||||
|
||||
```typescript
|
||||
const deleteResult = await supa
|
||||
.from('users')
|
||||
.delete()
|
||||
.eq('id', 1)
|
||||
.executeAs<User[]>();
|
||||
```
|
||||
|
||||
### 6. RPC 调用
|
||||
|
||||
```typescript
|
||||
const rpcResult = await supa
|
||||
.from('') // RPC 不需要 table
|
||||
.rpc('get_user_stats', { user_id: 1 } as UTSJSONObject)
|
||||
.executeAs<{ total_posts: number; total_likes: number }>();
|
||||
```
|
||||
|
||||
## 错误处理
|
||||
|
||||
```typescript
|
||||
try {
|
||||
const result = await supa
|
||||
.from('users')
|
||||
.select('*')
|
||||
.executeAs<User[]>();
|
||||
|
||||
if (result.error) {
|
||||
console.error('查询失败:', result.error);
|
||||
return;
|
||||
}
|
||||
|
||||
// 使用类型化的数据
|
||||
const users = result.data;
|
||||
if (users != null) {
|
||||
users.forEach(user => {
|
||||
// 现在有完整的类型提示
|
||||
console.log(user.name, user.email);
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('请求异常:', error);
|
||||
}
|
||||
```
|
||||
|
||||
## 向后兼容性
|
||||
|
||||
- 原有的 `execute()` 方法依然保持不变,返回 `UTSJSONObject`
|
||||
- 所有原有的链式方法都继续正常工作
|
||||
- `executeAs<T>()` 是附加功能,不影响现有代码
|
||||
|
||||
## 对比旧版本
|
||||
|
||||
### 旧版本(多方法)
|
||||
```typescript
|
||||
// 需要记住多个方法
|
||||
const users = await supa.selectAs<User[]>('users', filter, options);
|
||||
const inserted = await supa.insertAs<User>('users', data);
|
||||
const updated = await supa.updateAs<User[]>('users', filter, values);
|
||||
const deleted = await supa.deleteAs<User[]>('users', filter);
|
||||
const rpcResult = await supa.rpcAs<Stats>('func_name', params);
|
||||
```
|
||||
|
||||
### 新版本(统一方法)
|
||||
```typescript
|
||||
// 只需记住一个 executeAs<T>() 方法
|
||||
const users = await supa.from('users').select('*').executeAs<User[]>();
|
||||
const inserted = await supa.from('users').insert(data).executeAs<User>();
|
||||
const updated = await supa.from('users').update(values).eq('id', 1).executeAs<User[]>();
|
||||
const deleted = await supa.from('users').delete().eq('id', 1).executeAs<User[]>();
|
||||
const rpcResult = await supa.from('').rpc('func_name', params).executeAs<Stats>();
|
||||
```
|
||||
|
||||
## 优势
|
||||
|
||||
1. **API 简洁**:只需要记住一个 `executeAs<T>()` 方法
|
||||
2. **链式友好**:与所有现有方法完美组合
|
||||
3. **类型安全**:编译时检查 + 运行时转换(Android)
|
||||
4. **易于维护**:减少重复代码,统一处理逻辑
|
||||
5. **学习成本低**:从 `execute()` 到 `executeAs<T>()` 自然过渡
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. `UTSJSONObject.parse()` 仅在 Android 3.90+ 和 HarmonyOS 4.61+ 平台支持
|
||||
2. 其他平台使用类型断言,主要提供编译时类型检查
|
||||
3. 类型转换失败时会 fallback 到原始数据
|
||||
4. 建议在生产环境中进行充分的测试
|
||||
|
||||
## 技术实现
|
||||
|
||||
`executeAs<T>()` 内部:
|
||||
1. 调用原有的 `execute()` 方法获取结果
|
||||
2. 在 Android 平台使用 `UTSJSONObject.parse()` 进行类型转换
|
||||
3. 在其他平台使用类型断言提供类型提示
|
||||
4. 返回类型化的 `AkReqResponse<T>` 结果
|
||||
126
components/supadb/docs/TYPE_CONVERSION_FIX_SUMMARY.md
Normal file
126
components/supadb/docs/TYPE_CONVERSION_FIX_SUMMARY.md
Normal file
@@ -0,0 +1,126 @@
|
||||
# AkSupa 类型转换错误修复总结
|
||||
|
||||
## 问题描述
|
||||
|
||||
在实现 `executeAs<T>()` 和相关类型转换方法时,遇到了以下 UTS 编译错误:
|
||||
|
||||
1. **泛型类型参数错误**:`Cannot use 'T' as reified type parameter`
|
||||
2. **类型推断错误**:`推断类型是T?(可为空的T),但预期的是Any`
|
||||
3. **方法参数错误**:`Too many arguments for public open fun select`
|
||||
4. **属性访问错误**:`Unresolved reference: data`
|
||||
|
||||
## 修复方案
|
||||
|
||||
### 1. 移除泛型类型参数
|
||||
|
||||
**问题**:UTS 不支持 `UTSJSONObject.parse<T>()` 这种带泛型参数的调用方式。
|
||||
|
||||
**解决方案**:
|
||||
- 将 `item.parse<T>()` 改为 `item.parse()`
|
||||
- 将 `result.data.parse<T>()` 改为 `result.data.parse()`
|
||||
- 使用类型断言 `as T` 来提供类型提示
|
||||
|
||||
```typescript
|
||||
// 修复前
|
||||
convertedData = result.data.parse<T>();
|
||||
|
||||
// 修复后
|
||||
convertedData = result.data.parse();
|
||||
```
|
||||
|
||||
### 2. 简化方法签名
|
||||
|
||||
**问题**:`_convertResponse<T>()` 方法的泛型签名在 UTS 中无法正确处理。
|
||||
|
||||
**解决方案**:
|
||||
- 将 `_convertResponse<T>()` 改为 `_convertResponse()`
|
||||
- 返回类型改为 `AkReqResponse<any>`
|
||||
- 在调用处使用类型断言 `as AkReqResponse<T>`
|
||||
|
||||
```typescript
|
||||
// 修复前
|
||||
private _convertResponse<T>(result: AkReqResponse<any>): AkReqResponse<T>
|
||||
|
||||
// 修复后
|
||||
private _convertResponse(result: AkReqResponse<any>): AkReqResponse<any>
|
||||
```
|
||||
|
||||
### 3. 统一类型处理
|
||||
|
||||
**问题**:不同平台的类型处理逻辑不一致。
|
||||
|
||||
**解决方案**:
|
||||
- Android 平台:使用 `UTSJSONObject.parse()` 进行真正的类型转换
|
||||
- 其他平台:直接返回原始结果,通过类型断言提供类型提示
|
||||
|
||||
```typescript
|
||||
// Android 平台
|
||||
convertedData = result.data.parse();
|
||||
|
||||
// 其他平台
|
||||
return result; // 直接返回原始结果
|
||||
```
|
||||
|
||||
### 4. 空值处理优化
|
||||
|
||||
**问题**:`parse()` 方法可能返回 `null`,需要安全处理。
|
||||
|
||||
**解决方案**:
|
||||
- 增加 `null` 检查:`parsed != null ? parsed : item`
|
||||
- 保持原始数据作为 fallback
|
||||
|
||||
```typescript
|
||||
const parsed = item.parse();
|
||||
convertedArray.push(parsed != null ? parsed : item);
|
||||
```
|
||||
|
||||
## 修复的方法列表
|
||||
|
||||
### AkSupaQueryBuilder 类
|
||||
- ✅ `executeAs<T>()` - 链式查询的类型转换执行
|
||||
|
||||
### AkSupa 类
|
||||
- ✅ `selectAs<T>()` - 查询并类型转换
|
||||
- ✅ `insertAs<T>()` - 插入并类型转换
|
||||
- ✅ `updateAs<T>()` - 更新并类型转换
|
||||
- ✅ `deleteAs<T>()` - 删除并类型转换
|
||||
- ✅ `rpcAs<T>()` - RPC调用并类型转换
|
||||
- ✅ `_convertResponse()` - 私有类型转换方法
|
||||
|
||||
## 平台兼容性
|
||||
|
||||
| 平台 | 处理方式 | 效果 |
|
||||
|------|----------|------|
|
||||
| Android | `UTSJSONObject.parse()` | 真正的类型转换 |
|
||||
| iOS | 类型断言 `as T` | 编译时类型检查 |
|
||||
| Web | 类型断言 `as T` | 编译时类型检查 |
|
||||
| HarmonyOS | `UTSJSONObject.parse()` | 真正的类型转换 |
|
||||
|
||||
## 使用示例
|
||||
|
||||
```typescript
|
||||
// 现在可以正常使用了
|
||||
const users = await supa
|
||||
.from('users')
|
||||
.select('*')
|
||||
.executeAs<User[]>();
|
||||
|
||||
// 类型安全的访问
|
||||
users.data?.forEach(user => {
|
||||
console.log(user.name); // 有完整的类型提示
|
||||
});
|
||||
|
||||
// 直接方法调用
|
||||
const result = await supa.selectAs<User[]>('users');
|
||||
```
|
||||
|
||||
## 技术要点
|
||||
|
||||
1. **UTS 限制**:不支持泛型的 reified 类型参数
|
||||
2. **类型安全**:通过编译时类型断言提供类型提示
|
||||
3. **运行时转换**:在支持的平台上进行真正的类型转换
|
||||
4. **向后兼容**:原有的 `.execute()` 方法保持不变
|
||||
|
||||
## 总结
|
||||
|
||||
修复后的代码在保持类型安全的同时,完全兼容 UTS 的编译要求。在 Android 和 HarmonyOS 平台上提供真正的类型转换,在其他平台上提供编译时类型检查,为开发者提供了更好的开发体验。
|
||||
56
components/supadb/docs/aksupareal.md
Normal file
56
components/supadb/docs/aksupareal.md
Normal file
@@ -0,0 +1,56 @@
|
||||
GET wss://ak3.oulog.com/realtime/v1/websocket?apikey=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJzZXJ2aWNlX3JvbGUiLAogICAgImlzcyI6ICJzdXBhYmFzZS1kZW1vIiwKICAgICJpYXQiOiAxNjQxNzY5MjAwLAogICAgImV4cCI6IDE3OTk1MzU2MDAKfQ.DaYlNEoUrrEn2Ig7tqibS-PHK5vgusbcbo7X36XVt4Q&vsn=1.0.0 HTTP/1.1
|
||||
Host: ak3.oulog.com
|
||||
Connection: Upgrade
|
||||
Pragma: no-cache
|
||||
Cache-Control: no-cache
|
||||
User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 16_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.6 Mobile/15E148 Safari/604.1
|
||||
Upgrade: websocket
|
||||
Origin: http://localhost:5174
|
||||
Sec-WebSocket-Version: 13
|
||||
Accept-Encoding: gzip, deflate, br, zstd
|
||||
Accept-Language: zh-CN,zh;q=0.9
|
||||
Sec-WebSocket-Key: dJtuVuI1PWGVjC2E/qCDbQ==
|
||||
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
|
||||
|
||||
HTTP/1.1 101 Switching Protocols
|
||||
Server: nginx
|
||||
Date: Thu, 03 Jul 2025 04:03:55 GMT
|
||||
Connection: upgrade
|
||||
cache-control: max-age=0, private, must-revalidate
|
||||
sec-websocket-accept: XzR5+Z20bTKH4Ytm23KUTpQmDKE=
|
||||
upgrade: websocket
|
||||
Access-Control-Allow-Origin: *
|
||||
X-Kong-Upstream-Latency: 1
|
||||
X-Kong-Proxy-Latency: 0
|
||||
Via: kong/2.8.1
|
||||
|
||||
|
||||
|
||||
GET wss://ak3.oulog.com/realtime/v1/websocket?apikey=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJzZXJ2aWNlX3JvbGUiLAogICAgImlzcyI6ICJzdXBhYmFzZS1kZW1vIiwKICAgICJpYXQiOiAxNjQxNzY5MjAwLAogICAgImV4cCI6IDE3OTk1MzU2MDAKfQ.DaYlNEoUrrEn2Ig7tqibS-PHK5vgusbcbo7X36XVt4Q&vsn=1.0.0 HTTP/1.1
|
||||
Host: ak3.oulog.com
|
||||
Connection: Upgrade
|
||||
Pragma: no-cache
|
||||
Cache-Control: no-cache
|
||||
User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 16_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.6 Mobile/15E148 Safari/604.1
|
||||
Upgrade: websocket
|
||||
Origin: http://localhost:5173
|
||||
Sec-WebSocket-Version: 13
|
||||
Accept-Encoding: gzip, deflate, br, zstd
|
||||
Accept-Language: zh-CN,zh;q=0.9
|
||||
Sec-WebSocket-Key: ZNkWHFYshDAoPrErr9EY9w==
|
||||
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
|
||||
|
||||
HTTP/1.1 101 Switching Protocols
|
||||
Server: nginx
|
||||
Date: Thu, 03 Jul 2025 07:05:31 GMT
|
||||
Connection: upgrade
|
||||
cache-control: max-age=0, private, must-revalidate
|
||||
sec-websocket-accept: SV8HQ/NAJvS8eQcHVMmIdMRWcb4=
|
||||
upgrade: websocket
|
||||
Access-Control-Allow-Origin: *
|
||||
X-Kong-Upstream-Latency: 3
|
||||
X-Kong-Proxy-Latency: 1
|
||||
Via: kong/2.8.1
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user