# @bringg/dashboard-sdk 中文文档

规范地址：https://npmcn.com/package/%40bringg/dashboard-sdk/

版本：10\.0\.0
npm 元数据更新时间：2026-11-10T09:08:39.323Z
中文译文更新时间：2026-11-10T09:13:37.400Z
软件包许可：ISC

本文由上游 README 翻译，可能存在偏差，请结合原文核对 API、命令与配置。版权与许可归原作者所有。

原始 npm 页面：https://www.npmjs.com/package/%40bringg/dashboard-sdk
原文对照：https://npmcn.com/package/%40bringg/dashboard-sdk/?lang=original

## 关键信息（来自 npm 元数据）

- 包体积（解压后）：27.7 MB，1172 个文件
- 模块格式：CommonJS
- TypeScript 类型：包内自带
- Node.js 要求：22\.\*
- 运行依赖：14 个
- 首次发布：2018-10-03T16:24:07.054Z
- 最新版本发布：2026-11-10T09:08:38.760Z
- 近 30 天下载量：3804（2026-10-09 至 2026-11-07，npm 官方下载统计）
- 已发布版本数：1220（近 12 个月 186 个）

## 中文简介

带入仪表板 SDK

## 安装

```sh
npm install @bringg/dashboard-sdk
```

也可以使用：`pnpm add @bringg/dashboard-sdk`、`yarn add @bringg/dashboard-sdk`、`bun add @bringg/dashboard-sdk`

## README

[![codecov](https://codecov.io/gh/bringg/dashboard-sdk/branch/master/graph/badge.svg?token=T61tuD5MYe)](https://codecov.io/gh/bringg/dashboard-sdk)

# 带格・达什博德・斯迪克

## 实例:

#### 网易 (QQ ES5)

```html
<!doctype html>
<html lang="en">
<head>
  <!-- ... -->
  <script src="/bringg-dashboard-sdk.js"></script>
</head>
<body>
<!-- ... -->
<script>
BringgDashboardSDK.initWithEmail(email, password).then(bringgDashboardSDK => {
  bringgDashboardSDK.merchant.get().then(console.log).catch(console.error);
  bringgDashboardSDK.merchantConfiguration.get().then(console.log).catch(console.error);
});

BringgDashboardSDK.initWithAuthToken(region, authToken).then(bringgDashboardSDK => {
  bringgDashboardSDK.merchant.get().then(console.log).catch(console.error);
  bringgDashboardSDK.merchantConfiguration.get().then(console.log).catch(console.error);
});
</script>
</body>
</html>
```

#### 节点.js(QQES5)

```javascript
const BringgDashboardSDK = require("bringg-dashboard-sdk");

BringgDashboardSDK.initWithEmail(email, password).then(bringgDashboardSDK => {
  bringgDashboardSDK.merchant.get().then(console.log).catch(console.error);
  bringgDashboardSDK.merchantConfiguration.get().then(console.log).catch(console.error);
});

BringgDashboardSDK.initWithAuthToken(region, authToken).then(bringgDashboardSDK => {
  bringgDashboardSDK.merchant.get().then(console.log).catch(console.error);
  bringgDashboardSDK.merchantConfiguration.get().then(console.log).catch(console.error);
});
```

#### 类型脚本 (\\\\ 2.6)

```javascript
import BringgDashboardSDK = require("bringg-dashboard-sdk");

async function runAwait() {
  try {
    const bringgDashboardSDK = await BringgDashboardSDK.initWithEmail(email, password);
    console.log(await bringgDashboardSDK.merchant.get());
    console.log(await bringgDashboardSDK.merchantConfiguration.get());
  } catch (e) {
    console.error(e);
  }

  try {
    const bringgDashboardSDK = await BringgDashboardSDK.initWithAuthToken(region, authToken);
    console.log(await bringgDashboardSDK.merchant.get());
    console.log(await bringgDashboardSDK.merchantConfiguration.get());
  } catch (e) {
    console.error(e);
  }
}

runAwait();
```

### 正在测试

```bash
yarn test
```

### 以监视模式运行测试

```bash
yarn jest
```

### 用 tsLint 输入代码

```bash
yarn lint
```

### 用更美的代码修复您的代码

```bash
yarn prettier
```

### 修改您的代码, 并用一个命令修正它( 将会运行更漂亮和更漂亮)

```bash
yarn fix
```

### 编译你出色的代码制作

```bash
yarn prod
```

# DashboardSDK - 编写新实体的准则 - 10/4/19

每个实体应有3个部分——公共API,实体商店,Http服务.

# 上一个状态

比如我们想揭露 `VehicleType` 我们的最终用户, 我们先到sdk再加 `Actions` 文件夹.

代码示例

```javascript
export enum VehicleTypesActionTypes {
  GET_VEHICLE_TYPES = 'GET_VEHICLE_TYPES',
  MARK_VEHICLE_TYPES_FETCHED = 'MARK_VEHICLE_TYPES_FETCHED',
  SAVE_REQUEST_ERROR = 'SAVE_REQUEST_ERROR',
}

export const Routes = {
  GET_VEHICLE_TYPES: new Route('/vehicle_types', HttpMethod.GET),
};

export function storeVehicleTypesAction(vehicleTypes: VehicleType[]): Actions<VehicleTypesActionTypes> {
  return {
    type: VehicleTypesActionTypes.GET_VEHICLE_TYPES,
    payload: vehicleTypes,
  };
}

export function markVehicleTypesFetchedAction(isFetched: boolean): Actions<VehicleTypesActionTypes> {
  return {
    type: VehicleTypesActionTypes.MARK_VEHICLE_TYPES_FETCHED,
    payload: isFetched,
  };
}

export function saveRequestErrorAction(requestType: VehicleTypesRequests, error: Error): Actions<VehicleTypesActionTypes> {
  return {
    type: VehicleTypesActionTypes.SAVE_REQUEST_ERROR,
    payload: {
      requestType,
      error,
    },
  };
}

export const vehicleTypessExtractor = (response: VehicleTypesResponse) => response.vehicle_types;

export const getVehicleTypesRequestAction = (sessionService: SessionBasedService): any => async (dispatch): Promise<Actions<VehicleTypesActionTypes>> => {
  {
    try {
      const vehicleTypes: VehicleType[] = await sessionService.handleAuthorizedRequest<VehicleTypesResponse, VehicleType[]>(
        Routes.GET_VEHICLE_TYPES,
        vehicleTypessExtractor,
        BringgException.serviceException('failed to get vehicles'),
      );

      dispatch(markVehicleTypesFetchedAction(true));

      return await dispatch(storeVehicleTypesAction(vehicleTypes));
    } catch (e) {
      await dispatch(saveRequestErrorAction(VehicleTypesRequests.GET_VEHICLE_TYPES, e));
      throw e;
    }
  }
};

```

我们继续下一个文件夹 `Reducers`。 。 。 .

代码示例

```javascript
export const initState = fromJS({
  items: {},
  requests: {},
  fetched: false,
});

type requestErrorLog = requestErrors<VehicleTypesRequests>;

export type vehicleTypesState = ImmutableMap<{
  items: Map<number, VehicleType>;
  requests: ImmutableMap<requestErrorLog>;
  fetched: boolean;
}>;

export const storeVehicleTypes = (state: vehicleTypesState, vehicleTypes: VehicleType[]): vehicleTypesState =>
  state.set('items', immutableKeyBy(vehicleTypes, 'id'));

export const markVehicleTypesFetched = (state: vehicleTypesState, isFetched: boolean = true) => state.setIn(['fetched'], isFetched);

export const logRequestError = (state, requestType: VehicleTypesRequests, error: Error) => {
  return state.withMutations(state =>
    state.setIn(['requests', requestType, 'error'], error.toString()).setIn(['requests', requestType, 'timestamp'], Date.now()),
  );
};

export const vehicleTypesReducers = (state: vehicleTypesState = initState, action): vehicleTypesState => {
  switch (action.type) {
    case VehicleTypesActionTypes.SAVE_REQUEST_ERROR:
      return logRequestError(state, action.payload.requestType, action.payload.error);
    case VehicleTypesActionTypes.GET_VEHICLE_TYPES:
      return storeVehicleTypes(state, action.payload);
    case VehicleTypesActionTypes.MARK_VEHICLE_TYPES_FETCHED:
      return markVehicleTypesFetched(state, action.payload);
    default:
      return state;
  }
};

```

然后我们再加一个 `Service` 文件夹.

代码示例

```javascript
export default class VehicleTypesService extends SessionBasedService {
  private store: Redux.Store<CompleteStateStructure>;

  constructor(session: Session) {
    super(session.config.getApiEndpoint(), session);
    this.store = session.state.store;
  }

  @singleConcurrent()
  public async getAll(): Promise<VehicleType[]> {
    if (!this.areVehicleTypesFetched()) {
      await this.store.dispatch(getVehicleTypesRequestAction(this));
    }

    return this.getAllVehicleTypes();
  }

  private getAllVehicleTypes = (): VehicleType[] => {
    return this.store
      .getState()
      .vehicleTypes.getIn(['items'])
      .toList()
      .toJS();
  };

  private areVehicleTypesFetched = (): boolean => {
    return this.store.getState().vehicleTypes.getIn(['fetched']);
  };
}


```

然后,我们终于可以暴露我们的 `API` 文件夹 :)

代码示例

```javascript
export default class VehicleTypes {
  private vehicleTypesService: VehicleTypesService;

  constructor(session: Session) {
    this.vehicleTypesService = new VehicleTypesService(session);
  }

  public async getAll(): Promise<VehicleType[]> {
    return await this.vehicleTypesService.getAll();
  }
}
```

近两百行的代码 只是为了揭露 `getAll` 联 合 国 `VehicleTypes`。 。 。 .

我们试图通过创建程序来简化程序 `BaseStore` 并且在每个新实体商店中使用,而不是每次重写.

## 实体存储

我们希望每个实体国家随时更新(http要求、实时事件), 所以我们用商店管理课来做.

从现在开始,我们可以用一个新班的名字 `BaseStore` 这将是我们每个实体的基础,并管理其国家.

示例:

```typescript
export default class ChatConversationStore extends BaseStore<ChatConversation>
```

在这里,我们可以扩展我们的 `BaseStore` 并且无论我们认为它适合我们开发的新实体(如果存在,从商店取出,如果不是从服务器取出并存储它的话).

```typescript
  async getConversation(id: number): Promise<ChatConversation> {
    const chatConversation = this.getItem(id) || this._fetchConversation(id);

    return await chatConversation;
  }
```

## Http 服务

Http服务在sdk上几乎完全相同,这里就是简单的例子.

```typescript
  GET_CHAT_CONVERSATION: new Route('/chat_conversations/{:id}', HttpMethod.GET)

  public async getChatConversation(id): Promise<ChatConversation> {
    const chatConversationResponse:  ChatConversationResponse = await this.handleAuthorizedRequest<ChatConversationResponse, ChatConversationResponse>(
      Routes.GET_CHAT_CONVERSATION, //route
      defaultExtractor, // extractor func can be passed here
      BringgException.serviceException('Failed to get chat conversation'),
      undefined, //payload
      { id }, //route params
      {}, // query params
    );

    return chatConversationResponse.conversation;
  }
```

## 公共 API

在这里,我们决定我们要向终端用户曝光的终点和事件,这将会从实体商店调用.

示例 `ChatConversation`

```typescript
this.onItemRemoved = this.chatConversationStore.onItemRemoved; // remove event

public getConversation(id: number): Promise<ChatConversation> {
    return this.chatConversationStore.getConversation(id); // get item endpoint
}
```

## 基地

我们在这里执行 [RxJS 软件](http://reactivex.io/), (中文(简体) ),

我们有我们的主要物品流 `$items` 在每一个动作( 创建, 更新, remove) 上, 我们发送到流中, 并相应地汇总最更新的状态 .

每个商店扩展此类可以使用 `$items` stream to group what he wants data. (例如,从任务流中跳出只打开的任务. )

```typescript
  state$: Observable<Map<number, T>>; // aggregated state from main stream
  protected items$: Subject<Action>; // 1 main stream of items

  // Event Handlers
  protected onItemUpdateEvent: (item: T) => void = _.noop;
  protected onItemCreatedEvent: (item: T) => void = _.noop;
  protected onItemRemovedEvent: (item: number) => void = _.noop;
  protected onListUpdateEvent: (items: T[]) => void = _.noop;

  getItem = (itemId): T // Get Item From Store By Id

  addToStore(item: T) // Add item to store

  updateInStore(item: T) // update item in store

  getItems = (): T[] // get array of items of latest state in store

  addItems(items: T[]) // add array of items

  onItemCreated = (fn: (item: T) => void) => // set event handler for item removed

  onItemUpdate = (fn: (item: T) => void) => // set event handler for item updated

  onItemRemoved = (fn: (itemId: number) => void) // set event handler for item removed

  onListUpdate = (fn: (item: T[]) => void) // set event handler for list update

```

## 实体 发电机

为了节省时间,让你的生活更加轻松,有一个脚本来生成基础 需要执行.

您可以使用: npm 运行实体生成器 \[名\]\[bringg-type-name\] 运行它

脚本将在 src 文件夹内创建一个名为 \[name\] 的文件夹.

文件夹将包括 Service、 Store 和一些具有基本执行的文件 根据我们的公约.

## 下一步:

为了改进我们的SDK 和我们的发展过程.

-   将 Store 和服务合并为 . (而不是复制一直粘贴同样的服务)

## 常见问题

### @bringg/dashboard-sdk 是什么？

带入仪表板 SDK

### 如何安装 @bringg/dashboard-sdk？

在项目目录运行 npm install @bringg/dashboard-sdk，或使用 pnpm add / yarn add / bun add。

### @bringg/dashboard-sdk 支持 TypeScript 吗？

支持。包内自带 TypeScript 类型声明（package\.json 声明了 types 入口），安装后即可获得类型提示，无需再安装 @types 包。

### @bringg/dashboard-sdk 支持 ESM 还是 CommonJS？

以 CommonJS 形式发布，可以直接 require\(\)；在 ES Module 项目中也可以用 import 引入（Node\.js 会把 module\.exports 作为默认导出）。

### @bringg/dashboard-sdk 需要什么版本的 Node\.js？

package\.json 的 engines 字段要求 Node\.js 22\.\*。版本不符时 npm 默认只给出警告，开启 engine-strict 后会拒绝安装。

### @bringg/dashboard-sdk 可以商用吗？

@bringg/dashboard-sdk 使用 ISC 许可。宽松许可：允许商业使用、修改和再分发，通常只需在分发时保留原版权与许可声明。以上为概括，不构成法律意见，请以许可原文为准。

### @bringg/dashboard-sdk 的下载量有多少？

根据 npm 官方下载统计，@bringg/dashboard-sdk 在 2026/10/09 – 2026/11/07 这 30 天内被下载 3,804 次，日均约 127 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入，适合横向比较热度，不能直接等同于使用人数。

### @bringg/dashboard-sdk 还在维护吗？

最新版本 10\.0\.0 发布于 2026/11/10（今天）；至今共发布 1220 个版本，其中过去 12 个月发布了 186 个；首次发布于 2018/10/04。发布频率只是参考信号：功能稳定的工具可能很少需要更新，建议结合源码仓库的 issue 和提交记录判断。

