@lovrabet/sdk 1.2.9-beta.0 → 1.3.0-beta.2

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.
@@ -1,20 +1,42 @@
1
1
  import type { HttpClient } from "../http/http-client";
2
- import type { FxResult } from "./types";
2
+ /**
3
+ * BFF 客户端请求参数
4
+ */
5
+ export interface BffExecuteRequest {
6
+ /** 脚本名称(endpoint 函数名) */
7
+ scriptName: string;
8
+ /** 请求体参数(可选) */
9
+ params?: Record<string, any>;
10
+ /** Fetch 请求选项(可选) */
11
+ options?: RequestInit;
12
+ }
3
13
  /**
4
14
  * BFF 客户端 - 调用 Backend For Frontend 端点
5
15
  *
16
+ * 与其他 SDK 接口保持一致的响应处理逻辑:
17
+ * - 成功:返回 data(业务数据)
18
+ * - 失败:抛出 LovrabetError 异常(由 processResponse 处理)
19
+ *
6
20
  * @example
7
21
  * ```typescript
8
22
  * // 无参数调用
9
- * const result = await client.bff.execute('getBundleTemplates');
10
- * if (result.success) {
11
- * console.log(result.data);
12
- * }
23
+ * const templates = await client.bff.execute({
24
+ * scriptName: 'getBundleTemplates'
25
+ * });
26
+ * templates.forEach(template => console.log(template.name));
13
27
  *
14
28
  * // 带参数调用
15
- * const result = await client.bff.execute('calculatePrice', {
16
- * productId: '123',
17
- * quantity: 10
29
+ * const price = await client.bff.execute({
30
+ * scriptName: 'calculatePrice',
31
+ * params: { productId: '123', quantity: 10 }
32
+ * });
33
+ * console.log('Price:', price);
34
+ *
35
+ * // 带 Fetch 选项
36
+ * const result = await client.bff.execute({
37
+ * scriptName: 'getData',
38
+ * params: { id: '123' },
39
+ * options: { headers: { 'X-Custom-Header': 'value' } }
18
40
  * });
19
41
  *
20
42
  * // 带类型提示
@@ -23,10 +45,9 @@ import type { FxResult } from "./types";
23
45
  * name: string;
24
46
  * items: string[];
25
47
  * }
26
- * const result = await client.bff.execute<BundleTemplate>('getBundleTemplates');
27
- * if (result.success && result.data) {
28
- * result.data.forEach(template => console.log(template.name));
29
- * }
48
+ * const templates = await client.bff.execute<BundleTemplate>({
49
+ * scriptName: 'getBundleTemplates'
50
+ * });
30
51
  * ```
31
52
  */
32
53
  export declare class BffClient {
@@ -36,9 +57,9 @@ export declare class BffClient {
36
57
  /**
37
58
  * 调用 Backend For Frontend (BFF) 端点
38
59
  *
39
- * @param scriptName 脚本名称(endpoint 函数名)
40
- * @param bodyParams 请求体参数(可选)
41
- * @returns Function 执行结果(包含 success 和 data)
60
+ * @param request 请求参数
61
+ * @returns BFF 函数返回的业务数据
62
+ * @throws {LovrabetError} HTTP 请求失败时抛出异常
42
63
  */
43
- execute<T = any>(scriptName: string, bodyParams?: Record<string, any>): Promise<FxResult<T>>;
64
+ execute<T = any>(request: BffExecuteRequest): Promise<T>;
44
65
  }
@@ -28,11 +28,17 @@ export declare class ApiNamespace {
28
28
  *
29
29
  * @example
30
30
  * ```typescript
31
- * // 推荐用法
32
- * const data = await client.sql.execute('fc8e7777-06e3847d');
31
+ * // 推荐用法(对象参数)
32
+ * const data = await client.sql.execute({
33
+ * sqlCode: 'fc8e7777-06e3847d',
34
+ * params: { userId: '123' }
35
+ * });
33
36
  *
34
37
  * // 别名用法(兼容)
35
- * const data = await client.api.sql('fc8e7777-06e3847d');
38
+ * const data = await client.api.sql({
39
+ * sqlCode: 'fc8e7777-06e3847d',
40
+ * params: { userId: '123' }
41
+ * });
36
42
  * ```
37
43
  */
38
44
  get sql(): SqlClient["execute"];
@@ -51,11 +57,15 @@ export declare class ApiNamespace {
51
57
  *
52
58
  * @example
53
59
  * ```typescript
54
- * // 推荐用法
55
- * const result = await client.bff.execute('getBundleTemplates');
60
+ * // 推荐用法(对象参数)
61
+ * const result = await client.bff.execute({
62
+ * scriptName: 'getBundleTemplates'
63
+ * });
56
64
  *
57
65
  * // 别名用法(兼容)
58
- * const result = await client.api.bff('getBundleTemplates');
66
+ * const result = await client.api.bff({
67
+ * scriptName: 'getBundleTemplates'
68
+ * });
59
69
  * ```
60
70
  */
61
71
  get bff(): BffClient["execute"];
@@ -5,24 +5,26 @@ import type { SqlExecuteResult } from "./types";
5
5
  *
6
6
  * @example
7
7
  * ```typescript
8
- * // 方式1:直接传参(推荐)
8
+ * // 推荐:对象参数
9
+ * const data = await client.sql.execute({
10
+ * sqlCode: 'fc8e7777-06e3847d',
11
+ * params: { userId: '123', startDate: '2025-01-01' }
12
+ * });
13
+ *
14
+ * // 兼容:直接传参
9
15
  * const data = await client.sql.execute('fc8e7777-06e3847d', {
10
16
  * userId: '123',
11
17
  * startDate: '2025-01-01'
12
18
  * });
13
19
  *
14
- * // 方式2:对象参数(兼容 customSql.execute)
15
- * const data = await client.sql.execute({
16
- * sqlCode: 'fc8e7777-06e3847d',
17
- * params: { userId: '123' }
18
- * });
19
- *
20
20
  * // 带类型提示
21
21
  * interface PageStat {
22
22
  * creation_date: string;
23
23
  * page_count: number;
24
24
  * }
25
- * const data = await client.sql.execute<PageStat>('fc8e7777-06e3847d');
25
+ * const data = await client.sql.execute<PageStat>({
26
+ * sqlCode: 'fc8e7777-06e3847d'
27
+ * });
26
28
  * ```
27
29
  */
28
30
  export declare class SqlClient {
@@ -32,8 +34,8 @@ export declare class SqlClient {
32
34
  * 执行自定义 SQL 查询
33
35
  *
34
36
  * 支持两种调用方式:
35
- * 1. execute(sqlCode, params) - 直接传参(推荐)
36
- * 2. execute({ sqlCode, params }) - 对象参数(兼容 customSql.execute)
37
+ * 1. execute({ sqlCode, params }) - 对象参数(推荐)
38
+ * 2. execute(sqlCode, params) - 直接传参(兼容)
37
39
  *
38
40
  * @returns SQL执行结果(包含 execSuccess 和 execResult)
39
41
  */
@@ -16,24 +16,6 @@ export interface SqlExecuteResult<T = Record<string, any>> {
16
16
  /** SQL 查询结果数组 */
17
17
  execResult?: T[];
18
18
  }
19
- /**
20
- * Backend Function (独立端点) 请求参数
21
- */
22
- export interface FxRequest {
23
- /** 请求体参数,由调用方传递任意 JSON 数据 */
24
- [key: string]: any;
25
- }
26
- /**
27
- * Backend Function (独立端点) 执行结果数据
28
- */
29
- export interface FxResult<T = any> {
30
- /** Function 执行是否成功 */
31
- success: boolean;
32
- /** Function 返回的业务数据 */
33
- data?: T;
34
- /** 错误消息(执行失败时) */
35
- message?: string;
36
- }
37
19
  /**
38
20
  * 用户信息
39
21
  */
@@ -12,7 +12,7 @@ export declare class OpenApiModel extends AbstractBaseModel {
12
12
  /**
13
13
  * OpenAPI 模式的请求体构建策略
14
14
  * 认证信息(token、timeStamp)由 HttpClient 自动添加到请求头(Header)中
15
- * 请求体只包含业务数据
15
+ * 请求体格式:{ appCode, datasetCode, paramMap }
16
16
  */
17
17
  protected buildRequestBody(method: string, data: any, sortList?: SortList): any;
18
18
  /**
@@ -6,6 +6,15 @@
6
6
  * @returns {boolean} 如果在浏览器环境中返回 true,否则返回 false
7
7
  */
8
8
  export declare function isBrowser(): boolean;
9
+ /**
10
+ * 检测是否为开发环境
11
+ * @returns {boolean} 开发环境返回 true,否则返回 false
12
+ *
13
+ * 判断逻辑:
14
+ * - Node.js 环境:process.env.NODE_ENV !== 'production'
15
+ * - 浏览器环境:dev.lovrabet.com 或 localhost 或 127.* 或 192.168.*
16
+ */
17
+ export declare function isDevelopment(): boolean;
9
18
  /**
10
19
  * 在浏览器环境中使用 accessKey 时显示安全警告
11
20
  * @param message - 自定义警告消息(可选)
@@ -4,11 +4,13 @@ export declare class LovrabetError extends Error {
4
4
  readonly code?: string;
5
5
  readonly response?: any;
6
6
  readonly description?: ErrorDescription;
7
+ readonly cause?: unknown;
7
8
  constructor(message: string, options?: {
8
9
  status?: number;
9
10
  code?: string;
10
11
  response?: any;
11
12
  description?: ErrorDescription;
13
+ cause?: unknown;
12
14
  });
13
15
  toJSON(): {
14
16
  name: string;
@@ -17,6 +19,7 @@ export declare class LovrabetError extends Error {
17
19
  code: string;
18
20
  response: any;
19
21
  description: ErrorDescription;
22
+ cause: unknown;
20
23
  };
21
24
  }
22
25
  export declare function createErrorHandler(onError?: (error: any) => void): (error: any) => Promise<never>;
@@ -1,2 +1,6 @@
1
1
  export { LovrabetError, createErrorHandler } from "./errors";
2
- export { isBrowser, warnBrowserAccessKey } from './browser-detection';
2
+ export { isBrowser, isDevelopment, warnBrowserAccessKey } from './browser-detection';
3
+ export { safe } from './safe';
4
+ export type { SafeResult } from './safe';
5
+ export { sqlSafe } from './sql-safe';
6
+ export type { SqlSafeResult } from './sql-safe';
@@ -0,0 +1,54 @@
1
+ import { LovrabetError } from './errors';
2
+ /**
3
+ * 安全执行结果类型
4
+ *
5
+ * @example
6
+ * ```typescript
7
+ * const { data, error } = await safe(client.models.customer.filter({ ... }));
8
+ * if (error) {
9
+ * console.error(error.message, error.description);
10
+ * return;
11
+ * }
12
+ * // 使用 data
13
+ * ```
14
+ */
15
+ export interface SafeResult<T> {
16
+ /** 成功时的数据,失败时为 null */
17
+ data: T | null;
18
+ /** 失败时的错误对象,成功时为 null */
19
+ error: LovrabetError | null;
20
+ }
21
+ /**
22
+ * Promise 或返回 Promise 的函数类型
23
+ */
24
+ type PromiseLike<T> = Promise<T> | (() => Promise<T>);
25
+ /**
26
+ * 安全执行 Promise,将异常转换为返回值
27
+ *
28
+ * @param fn - Promise 或返回 Promise 的函数
29
+ * @returns 包含 data 和 error 的结果对象
30
+ *
31
+ * @example
32
+ * ```typescript
33
+ * // 直接传入 Promise
34
+ * const { data, error } = await safe(client.models.customer.filter({ where: { status: 'active' } }));
35
+ * if (error) {
36
+ * console.error(error.message);
37
+ * return;
38
+ * }
39
+ * console.log(data);
40
+ *
41
+ * // 传入函数(延迟执行)
42
+ * const { data, error } = await safe(() => client.models.customer.filter({ ... }));
43
+ *
44
+ * // 旧代码继续工作(抛异常模式)
45
+ * try {
46
+ * const data = await client.models.customer.filter({ ... });
47
+ * console.log(data);
48
+ * } catch (error) {
49
+ * console.error(error);
50
+ * }
51
+ * ```
52
+ */
53
+ export declare function safe<T>(fn: PromiseLike<T>): Promise<SafeResult<T>>;
54
+ export {};
@@ -0,0 +1,78 @@
1
+ import { LovrabetError } from './errors';
2
+ import type { SqlExecuteResult } from '../api/types';
3
+ /**
4
+ * sqlSafe 执行结果类型
5
+ *
6
+ * @example
7
+ * ```typescript
8
+ * const { data, error } = await sqlSafe(() => client.sql.execute(...));
9
+ * if (error) {
10
+ * console.error(error.message, error.code, error.cause);
11
+ * return;
12
+ * }
13
+ * // data 直接是查询结果数组
14
+ * data.forEach(row => console.log(row));
15
+ * ```
16
+ */
17
+ export interface SqlSafeResult<T> {
18
+ /** 成功时的查询结果数组,失败时为 null */
19
+ data: T[] | null;
20
+ /** 失败时的错误对象,成功时为 null */
21
+ error: LovrabetError | null;
22
+ }
23
+ /**
24
+ * Promise 或返回 Promise 的函数类型
25
+ */
26
+ type SqlPromiseLike<T> = Promise<SqlExecuteResult<T>> | (() => Promise<SqlExecuteResult<T>>);
27
+ /**
28
+ * 安全执行 SQL 查询,统一处理 HTTP 错误和业务逻辑错误
29
+ *
30
+ * @param fn - 返回 SqlExecuteResult 的 Promise 或函数
31
+ * @returns 包含 data(查询结果数组)和 error 的结果对象
32
+ *
33
+ * @example
34
+ * ```typescript
35
+ * // 基础用法
36
+ * const { data, error } = await sqlSafe(() =>
37
+ * client.sql.execute({ sqlCode: 'fc8e7777-06e3847d' })
38
+ * );
39
+ *
40
+ * if (error) {
41
+ * console.error('查询失败:', error.message);
42
+ * return;
43
+ * }
44
+ *
45
+ * // data 直接是查询结果数组
46
+ * console.log(`查询到 ${data.length} 条记录`);
47
+ * data.forEach(row => console.log(row));
48
+ *
49
+ * // 带类型提示
50
+ * interface UserStat {
51
+ * id: number;
52
+ * name: string;
53
+ * login_count: number;
54
+ * }
55
+ *
56
+ * const { data, error } = await sqlSafe<UserStat>(() =>
57
+ * client.sql.execute({ sqlCode: 'user-stats' })
58
+ * );
59
+ *
60
+ * if (error) {
61
+ * if (error.code === 'SQL_ERROR') {
62
+ * // 业务逻辑失败(execSuccess = false)
63
+ * console.error('SQL 执行失败:', error.cause);
64
+ * } else {
65
+ * // HTTP 错误(404、500 等)
66
+ * console.error('请求失败:', error.status, error.message);
67
+ * }
68
+ * return;
69
+ * }
70
+ *
71
+ * // data 是 UserStat[]
72
+ * data.forEach(stat => {
73
+ * console.log(`${stat.name}: ${stat.login_count} 次登录`);
74
+ * });
75
+ * ```
76
+ */
77
+ export declare function sqlSafe<T>(fn: SqlPromiseLike<T>): Promise<SqlSafeResult<T>>;
78
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lovrabet/sdk",
3
- "version": "1.2.9-beta.0",
3
+ "version": "1.3.0-beta.2",
4
4
  "license": "SEE LICENSE IN LICENSE",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.js",