Skip to content

Configuration

This guide helps you understand how configuration works in the Lovrabet SDK, so you can get started quickly and use it efficiently.

Why configuration?

Every dataset you access through the Lovrabet SDK has a unique datasetCode (for example, 8d2dcbae08b54bdd84c00be558ed48df). Without a configuration mechanism, your code would look like this:

TypeScript
// ❌ 没有配置:每次调用都要手动填写 appCode 和 datasetCode
const response = await fetch('/api/data', {
  body: JSON.stringify({
    appCode: 'my-app',
    datasetCode: '8d2dcbae08b54bdd84c00be558ed48df',
    // ...其他参数
  })
});

Configuration solves these pain points:

  • Configure once, use everywhere - no more typing appCode and datasetCode on every call
  • Cleaner code - client.models.dataset_xxx.filter() does it in one line
  • Type safety - TypeScript intellisense catches mistakes early
  • AI-friendly - datasetCodes are globally unique, so AI tools generate accurate code

The easiest path: use the Lovrabet CLI to generate the configuration file in one step.

💡 Haven't installed the CLI yet? Install it first following the CLI installation guide, then create a project with the 5-minute quick start.

Step 1: pull the configuration

Run this in your project root:

Bash
lovrabet api pull

📖 See the CLI API integration docs for detailed parameter descriptions.

The CLI pulls your dataset information from the platform and generates the configuration file src/api/api.ts:

TypeScript
// src/api/api.ts (CLI 自动生成)
import { registerModels, type ModelsConfig } from "@lovrabet/sdk";

export const LOVRABET_MODELS_CONFIG: ModelsConfig = {
  appCode: "app-c4c89304",
  models: [
    {
      datasetCode: "71494bcba13f4ec7858abe90794183ad",
      tableName: "users",
      alias: "users",
      name: "用户管理",
    },
    {
      datasetCode: "d26ed512e878461ca97d287a47606fd3",
      tableName: "orders",
      alias: "orders",
      name: "订单管理",
    },
  ],
} as const;

// 自动注册配置
registerModels(LOVRABET_MODELS_CONFIG);

Step 2: use the configuration

Create a client directly in your business code and go:

TypeScript
import { createClient } from "@lovrabet/sdk";
import "./api/api"; // 引入配置文件,自动注册

const client = createClient();

// 标准方式访问(推荐)- 使用 dataset_ 前缀 + datasetCode
const users = await client.models.dataset_71494bcba13f4ec7858abe90794183ad.filter();
const orders = await client.models.dataset_d26ed512e878461ca97d287a47606fd3.getOne("order-001");

💡 Why is the standard style recommended? datasetCodes are globally unique, so AI tools (such as Claude and Cursor) generate unambiguous code.

Step 3 (optional): use aliases

If the datasetCode is too long to read comfortably, use the alias defined in the configuration:

TypeScript
// 别名方式(语法糖)- 使用配置的 alias
const users = await client.models.users.filter();
const orders = await client.models.orders.getOne("order-001");

📌 Note: an alias is just a pointer — internally the SDK still uses the datasetCode, and everything behaves exactly as with the standard style.


Manual configuration (for special cases)

If you don't use the CLI, or need finer control, you can configure things by hand.

💡 Recommendation: in most cases, let the CLI generate the configuration — it saves time and effort.

Option 1: pre-registered configuration

Register the configuration with registerModels() first, then create clients anywhere:

TypeScript
import { registerModels, createClient } from "@lovrabet/sdk";

// 注册配置(通常在应用入口执行一次)
registerModels({
  appCode: "my-app",
  models: [
    {
      datasetCode: "8d2dcbae08b54bdd84c00be558ed48df",
      tableName: "users",
      alias: "users",  // 可选
      name: "用户表",  // 可选
    },
    {
      datasetCode: "a1b2c3d4e5f6789012345678abcdef12",
      tableName: "orders",
      alias: "orders",
      name: "订单表",
    },
  ],
});

// 在任意位置创建客户端(无需再传配置)
const client = createClient();

// 标准方式访问
const users = await client.models.dataset_8d2dcbae08b54bdd84c00be558ed48df.filter();

Good for:

  • Sharing one configuration across multiple modules
  • Keeping configuration separate from business logic

Option 2: pass the configuration directly

Pass a configuration object when creating the client:

TypeScript
import { createClient } from "@lovrabet/sdk";

const client = createClient({
  appCode: "my-app",
  models: [
    {
      datasetCode: "8d2dcbae08b54bdd84c00be558ed48df",
      tableName: "users",
      alias: "users",
    },
  ],
});

// 标准方式访问
const users = await client.models.dataset_8d2dcbae08b54bdd84c00be558ed48df.filter();

// 别名方式访问(语法糖)
const users = await client.models.users.filter();

Good for:

  • Quick tests or one-off usage
  • Full control over each client's configuration

Model access in depth

The SDK offers two ways to access models — functionally identical:

Access a model with the dataset_ prefix plus the datasetCode:

TypeScript
// 格式:client.models.dataset_[datasetCode]
const users = await client.models.dataset_8d2dcbae08b54bdd84c00be558ed48df.filter();
const order = await client.models.dataset_a1b2c3d4e5f6789012345678abcdef12.getOne("id");

Why is this the standard?

  • Globally unique - the datasetCode uniquely identifies a dataset and never collides
  • AI-friendly - AI tools can pin down the exact dataset, reducing hallucinations
  • No configuration needed - works even without pre-registered models

Alias style (syntactic sugar)

If the configuration defines an alias, you can use the shorter name:

TypeScript
// 格式:client.models.[alias]
const users = await client.models.users.filter();
const order = await client.models.orders.getOne("id");

About aliases:

  • 📌 Pure syntactic sugar - an alias is just a pointer; internally the datasetCode is used
  • 📌 Fully equivalent - all API methods and type hints are identical to the standard style
  • 📌 Better readability - easier for humans to scan

Comparison

StyleFormatCharacteristics
Standardclient.models.dataset_[datasetCode]Globally unique, AI-friendly, recommended
Aliasclient.models.[alias]Syntactic sugar, human-friendly, requires configuring an alias

Advanced configuration

Managing multiple projects

If you work on several projects at once, register multiple configurations and switch by name:

TypeScript
import { registerModels, createClient } from "@lovrabet/sdk";

// 注册多个项目配置
registerModels(CONFIG_A, "project-a");
registerModels(CONFIG_B, "project-b");

// 按名称创建不同项目的客户端
const clientA = createClient("project-a");
const clientB = createClient("project-b");

Extended ClientConfig options

Pass extra options when creating a client:

TypeScript
const client = createClient({
  apiConfigName: "default",     // 使用哪个预注册配置
  token: "your-auth-token",     // 用户认证 Token
  accessKey: "your-access-key", // OpenAPI 访问密钥
  secretKey: "your-secret-key", // OpenAPI 密钥
  serverUrl: "https://custom.api.com", // 自定义服务器地址
  options: {
    timeout: 30000,             // 请求超时时间(毫秒)
    onError: (error) => {       // 错误回调
      console.error("API Error:", error);
    },
    onRedirectToLogin: () => {  // 登录过期回调
      window.location.href = "/login";
    },
  },
});

Adding models dynamically

Add new models at runtime:

TypeScript
// 动态添加模型
client.addModel({
  datasetCode: "f7e6d5c4b3a2901234567890fedcba98",
  tableName: "products",
  alias: "products",
  name: "产品管理",
});

// 立即可用
const products = await client.models.dataset_f7e6d5c4b3a2901234567890fedcba98.filter();
// 或使用别名
const products = await client.models.products.filter();

Inspecting models

TypeScript
// 获取所有已配置的模型详情
const details = client.getModelListDetails();
// 返回: [{ datasetCode: '...', alias: 'users', name: '用户表' }, ...]

// 获取所有已注册的配置名称
import { getRegisteredConfigNames } from "@lovrabet/sdk";
console.log(getRegisteredConfigNames()); // ['default', 'project-a', 'project-b']

Configuration structure reference

ModelsConfig

TypeScript
interface ModelsConfig {
  appCode: string;           // 应用代码
  models: Array<{
    datasetCode: string;     // 数据集代码(必填,唯一标识)
    tableName: string;       // 数据表名(必填)
    alias?: string;          // 模型别名(可选,用于 client.models.alias 访问)
    name?: string;           // 显示名称(可选,用于 UI 展示)
  }>;
}

ClientConfig

TypeScript
interface ClientConfig {
  apiConfigName?: string;    // 预注册配置名称
  serverUrl?: string;        // 自定义服务器地址
  token?: string;            // 用户认证 Token
  accessKey?: string;        // OpenAPI 访问密钥
  secretKey?: string;        // OpenAPI 密钥
  options?: {
    timeout?: number;        // 请求超时时间(毫秒)
    onError?: (error: any) => void;
    onRedirectToLogin?: () => void;
  };
}

FAQ

Q: What's the difference between CLI-generated and manual configuration?

Functionally, none. The CLI simply generates the configuration code for you, sparing you the trouble of hunting down datasetCodes.

👉 How to generate configuration with the CLI

Q: Standard style or alias style — which should I use?

  • AI-assisted development (Cursor, Claude, etc.) → standard style dataset_xxx: globally unique, no ambiguity
  • Purely manual development → alias style users reads better
  • Mixed scenarios → both work; they are functionally identical

Q: What's the difference between alias and name?

  • alias: used to access the model in code, e.g. client.models.users
  • name: used for display in UIs, e.g. model lists in the admin console

Q: How do I migrate from the old configuration format?

v1.2.0 is fully backward compatible with the old object-format configuration, so there's no need to migrate right away. For new projects, we recommend the array format:

TypeScript
// 旧格式(仍然支持)
registerModels({
  appCode: "my-app",
  models: {
    users: { tableName: "users", datasetCode: "..." },
  },
});

// 新格式(推荐)
registerModels({
  appCode: "my-app",
  models: [
    { datasetCode: "...", tableName: "users", alias: "users" },
  ],
});

Next steps

CLI:

  • 🛠️ CLI installation guide - install the Lovrabet CLI
  • 🚀 5-minute quick start - create a project from scratch
  • 📡 API integration - detailed usage of lovrabet api pull

Going further with the SDK:

  • 🔐 Authentication - configure token or OpenAPI authentication
  • 📊 API guide - a deep dive into CRUD operations
  • 🚀 Advanced features - Filter API, SQL API, and more

基于飞书知识库同步生成,内容以飞书源文档为准