Token导航 LogoToken导航TokenDH.com
研究检索需要联网github未标认证来源可访问许可证需确认审计异常

bknd-crud-createbknd 增删改查创建

Agent Skill

bknd-crud-create 用于查找、检索和筛选相关信息,适合在 Codex、Claude、Cursor、Gemini CLI 中需要根据关键词、任务场景或来源线索快速定位候选结果时使用。可结合来源仓库、安装命令和原始 README 继续核验具体用法。安装前建议确认权限范围、维护状态,以及是否会触发联网、命令执行或文件读写。

总安装

306

周安装

13

GitHub Stars

3

下载量

107
CodexClaudeCursorGemini CLI

安装说明

本站只整理中文说明和来源信息,不托管安装包,也不代用户安装。

GitHub

来源数

2

许可证

unknown

最后核验

2026-05-01

来源状态

来源可访问

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:bknd-crud-create(bknd 增删改查创建)
来源仓库:https://github.com/cameronapak/bknd-skills
仓库路径:skills/bknd-crud-create
安装命令:
npx skills add https://github.com/cameronapak/bknd-skills --skill bknd-crud-create
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。该命令会通过 npx skills 从第三方来源获取 Skill;本站只展示命令,不托管安装包,也不自动执行。

skills.shnpx skills
npx skills add https://github.com/cameronapak/bknd-skills --skill bknd-crud-create

简介

bknd-crud-create 用于向数据库插入新记录,适合在 Codex、Claude、Cursor、Gemini CLI 中实现用户生成内容或系统初始化数据的写入。

  • 适用场景包括表单提交保存、API 集成数据落地及自动化脚本批量创建条目。
  • 核心能力是通过 SDK 或 REST API 发起 POST 请求完成 record 创建,支持返回完整元数据。
  • 使用方式建议先在 UI 模式下单条测试,稳定后再切换至 Code 模式嵌入业务逻辑。
  • 插入前应验证实体 schema 是否符合预期,避免因字段缺失导致请求失败。

SKILL.md

CRUD Create

Insert new records into your Bknd database using the SDK or REST API.

Prerequisites

  • Bknd project running (local or deployed)
  • Entity exists (use bknd-create-entity first)
  • SDK configured or API endpoint known

When to Use UI Mode

  • Quick one-off data entry
  • Manual testing during development
  • Non-technical users adding records

UI steps: Admin Panel > Data > Select Entity > Click "+" or "Add" > Fill form > Save

When to Use Code Mode

  • Application logic for user-generated content
  • Form submissions
  • API integrations
  • Automated record creation

Code Approach

Step 1: Set Up SDK Client

import { Api } from "bknd";

const api = new Api({
  host: "http://localhost:7654",  // Your Bknd server
});

// If auth required:
api.updateToken("your-jwt-token");

Step 2: Create Single Record

Use createOne(entity, data):

const { ok, data, error } = await api.data.createOne("posts", {
  title: "My First Post",
  content: "Hello world!",
  published: false,
});

if (ok) {
  console.log("Created post:", data.id);
} else {
  console.error("Failed:", error.message);
}

Step 3: Handle Response

The response object:

type CreateResponse = {
  ok: boolean;       // Success/failure
  data?: {           // Created record (if ok)
    id: number;      // Auto-generated ID
    // ...all fields with defaults applied
  };
  error?: {          // Error info (if !ok)
    message: string;
    code: string;
  };
};

Step 4: Create with Relations

Link to existing related records using $set:

// Link to single related record (many-to-one)
const { data } = await api.data.createOne("posts", {
  title: "New Post",
  author: { $set: 1 },  // Link to user with ID 1
});

// Link to multiple related records (many-to-many)
const { data } = await api.data.createOne("posts", {
  title: "Tagged Post",
  tags: { $set: [1, 2, 3] },  // Link to tag IDs 1, 2, 3
});

// Combine both
const { data } = await api.data.createOne("posts", {
  title: "Complete Post",
  content: "Full content here",
  author: { $set: userId },
  category: { $set: categoryId },
  tags: { $set: [tagId1, tagId2] },
});

Step 5: Create Multiple Records (Bulk)

Use createMany(entity, data[]):

const { ok, data } = await api.data.createMany("tags", [
  { name: "javascript" },
  { name: "typescript" },
  { name: "bknd" },
]);

// data is array of created records
console.log("Created", data.length, "tags");

REST API Approach

Create One

curl -X POST http://localhost:7654/api/data/posts \
  -H "Content-Type: application/json" \
  -d '{"title": "New Post", "content": "Hello!"}'

Create with Auth

curl -X POST http://localhost:7654/api/data/posts \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -d '{"title": "Protected Post"}'

Create Many

curl -X POST http://localhost:7654/api/data/tags \
  -H "Content-Type: application/json" \
  -d '[{"name": "tag1"}, {"name": "tag2"}]'

Create with Relations

curl -X POST http://localhost:7654/api/data/posts \
  -H "Content-Type: application/json" \
  -d '{"title": "Post", "author": {"$set": 1}}'

React Integration

Basic Form Submit

import { useApp } from "bknd/react";

function CreatePostForm() {
  const { api } = useApp();
  const [title, setTitle] = useState("");
  const [error, setError] = useState<string | null>(null);
  const [loading, setLoading] = useState(false);

  async function handleSubmit(e: React.FormEvent) {
    e.preventDefault();
    setLoading(true);
    setError(null);

    const { ok, data, error: apiError } = await api.data.createOne("posts", {
      title,
      published: false,
    });

    setLoading(false);

    if (ok) {
      console.log("Created:", data.id);
      setTitle("");
    } else {
      setError(apiError.message);
    }
  }

  return (
    <form onSubmit={handleSubmit}>
      <input
        value={title}
        onChange={(e) => setTitle(e.target.value)}
        placeholder="Post title"
        required
      />
      <button type="submit" disabled={loading}>
        {loading ? "Creating..." : "Create Post"}
      </button>
      {error && <p className="error">{error}</p>}
    </form>
  );
}

With SWR Revalidation

import { useApp } from "bknd/react";
import useSWR, { mutate } from "swr";

function PostsList() {
  const { api } = useApp();

  const { data: posts } = useSWR("posts", () =>
    api.data.readMany("posts").then((r) => r.data)
  );

  async function createPost(title: string) {
    const { ok, data } = await api.data.createOne("posts", { title });

    if (ok) {
      // Revalidate the posts list
      mutate("posts");
    }

    return { ok, data };
  }

  return (
    <div>
      <CreateForm onCreate={createPost} />
      <ul>
        {posts?.map((post) => (
          <li key={post.id}>{post.title}</li>
        ))}
      </ul>
    </div>
  );
}

Full Example

import { Api } from "bknd";

const api = new Api({ host: "http://localhost:7654" });

// Authenticate first (if required)
await api.auth.login({ email: "user@example.com", password: "password" });

// Create a user
const { data: user } = await api.data.createOne("users", {
  email: "newuser@example.com",
  name: "New User",
  role: "author",
});

// Create a post linked to user
const { data: post } = await api.data.createOne("posts", {
  title: "My First Blog Post",
  content: "This is the content of my post.",
  published: true,
  author: { $set: user.id },
});

// Create tags
const { data: tags } = await api.data.createMany("tags", [
  { name: "intro" },
  { name: "tutorial" },
]);

// Link tags to post (update after creation)
await api.data.updateOne("posts", post.id, {
  tags: { $set: tags.map((t) => t.id) },
});

console.log("Created post:", post.id, "with tags:", tags.length);

Field Default Handling

Bknd applies defaults for omitted fields:

// Entity definition
entity("posts", {
  title: text().required(),
  status: text({ default_value: "draft" }),
  view_count: number({ default_value: 0 }),
  created_at: date({ default_value: "now" }),
});

// Create with minimal data
const { data } = await api.data.createOne("posts", {
  title: "Just a title",  // Only required field
});

// Result includes defaults
console.log(data);
// {
//   id: 1,
//   title: "Just a title",
//   status: "draft",           // default applied
//   view_count: 0,             // default applied
//   created_at: "2025-01-20T..." // default applied
// }

Validation Handling

Bknd validates data against schema:

// Entity with constraints
entity("users", {
  email: text().required().unique(),
  name: text(),
});

// Missing required field
const { ok, error } = await api.data.createOne("users", {
  name: "No Email",
});
// ok: false, error: { message: "email is required" }

// Duplicate unique field
const { ok, error } = await api.data.createOne("users", {
  email: "existing@example.com",  // Already exists
});
// ok: false, error: { message: "UNIQUE constraint failed" }

Common Patterns

Create or Find Existing

async function createOrFind(
  api: Api,
  entity: string,
  data: object,
  uniqueField: string
) {
  // Try to find existing
  const { data: existing } = await api.data.readOneBy(entity, {
    where: { [uniqueField]: { $eq: data[uniqueField] } },
  });

  if (existing) {
    return { created: false, data: existing };
  }

  // Create new
  const { data: created } = await api.data.createOne(entity, data);
  return { created: true, data: created };
}

// Usage
const { created, data } = await createOrFind(
  api,
  "users",
  { email: "user@example.com", name: "User" },
  "email"
);

Create with Optimistic UI

function useCreatePost() {
  const { api } = useApp();
  const [posts, setPosts] = useState<Post[]>([]);

  async function createPost(title: string) {
    // Optimistic: add temp post immediately
    const tempId = `temp-${Date.now()}`;
    const tempPost = { id: tempId, title, status: "creating" };
    setPosts((prev) => [...prev, tempPost]);

    // Actual create
    const { ok, data } = await api.data.createOne("posts", { title });

    if (ok) {
      // Replace temp with real
      setPosts((prev) =>
        prev.map((p) => (p.id === tempId ? data : p))
      );
    } else {
      // Remove temp on failure
      setPosts((prev) => prev.filter((p) => p.id !== tempId));
    }

    return { ok, data };
  }

  return { posts, createPost };
}

Batch Create with Progress

async function batchCreate(
  api: Api,
  entity: string,
  items: object[],
  onProgress?: (done: number, total: number) => void
) {
  const results = [];
  const batchSize = 100;

  for (let i = 0; i < items.length; i += batchSize) {
    const batch = items.slice(i, i + batchSize);
    const { data } = await api.data.createMany(entity, batch);
    results.push(...data);

    onProgress?.(Math.min(i + batchSize, items.length), items.length);
  }

  return results;
}

// Usage
const items = generateItems(500);
await batchCreate(api, "products", items, (done, total) => {
  console.log(`Progress: ${done}/${total}`);
});

Common Pitfalls

Missing Required Fields

Problem: NOT NULL constraint failed

Fix: Include all required fields:

// Entity: email is required
entity("users", { email: text().required(), name: text() });

// Wrong - missing email
await api.data.createOne("users", { name: "Test" });

// Correct
await api.data.createOne("users", { email: "test@example.com", name: "Test" });

Invalid Relation ID

Problem: FOREIGN KEY constraint failed

Fix: Ensure related record exists:

// Wrong - author ID doesn't exist
await api.data.createOne("posts", { title: "Post", author: { $set: 999 } });

// Correct - verify first or handle error
const { data: author } = await api.data.readOne("users", authorId);
if (author) {
  await api.data.createOne("posts", { title: "Post", author: { $set: authorId } });
}

Unique Constraint Violation

Problem: UNIQUE constraint failed

Fix: Check before create or handle error:

// Option 1: Check first
const { data: exists } = await api.data.exists("users", {
  email: { $eq: email },
});
if (exists.exists) {
  throw new Error("Email already registered");
}
await api.data.createOne("users", { email, name });

// Option 2: Handle error
const { ok, error } = await api.data.createOne("users", { email, name });
if (!ok && error.message.includes("UNIQUE")) {
  throw new Error("Email already registered");
}

Not Handling Response

Problem: Assuming success without checking.

Fix: Always check ok:

// Wrong - assumes success
const { data } = await api.data.createOne("posts", { title });
console.log(data.id);  // data might be undefined!

// Correct
const { ok, data, error } = await api.data.createOne("posts", { title });
if (!ok) {
  throw new Error(error.message);
}
console.log(data.id);

Creating Without Auth

Problem: Unauthorized error.

Fix: Authenticate first or check permissions:

// Login first
await api.auth.login({ email, password });

// Or set token
api.updateToken(savedToken);

// Then create
await api.data.createOne("posts", { title });

Verification

After creating, verify the record:

const { ok, data } = await api.data.createOne("posts", { title: "Test" });

if (ok) {
  // Read back to verify
  const { data: fetched } = await api.data.readOne("posts", data.id);
  console.log("Created and verified:", fetched);
}

Or via admin panel: Admin Panel > Data > Select Entity > Find new record.

DOs and DON'Ts

DO:

  • Check the ok field before using data
  • Include all required fields
  • Verify related records exist before using $set
  • Handle unique constraint errors gracefully
  • Authenticate before creating protected records

DON'T:

  • Assume createOne always succeeds
  • Use non-existent IDs in $set
  • Ignore validation errors
  • Create without auth when permissions require it
  • Forget to revalidate caches after create

Related Skills

  • bknd-seed-data - Bulk initial data via seed function (server-side)
  • bknd-crud-read - Query records after creation
  • bknd-crud-update - Modify created records
  • bknd-define-relationship - Set up relations for $set linking
  • bknd-bulk-operations - Large-scale record creation

适合场景

01

用户想查找某类 Agent Skill 时

02

需要根据任务场景推荐可安装能力包时

03

需要对比不同来源的安装命令和来源信息时

能力概览

能力 1

按任务关键词查找相关 Skills

能力 2

展示可复制的安装命令

能力 3

保留来源站点、仓库和原始说明,方便继续核验

能力 4

展示第三方安全扫描或审计结果

安装后应在对应宿主中按原始 README 的触发条件使用;具体调用方式请以来源页面和 README 为准。

平台分布

Codex

38.7%
按下载量换算41

Claude

27.05%
按下载量换算29

Cursor

19.84%
按下载量换算21

Gemini CLI

9.95%
按下载量换算11

安全审计

Gen Agent Trust Hub

通过

Socket

通过

Snyk

未通过

权限和风险

需要联网

该 Skill 可能需要联网访问来源站点、仓库或外部 API;具体网络访问范围需要结合源码和 README 复核。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。来源安全扫描存在 warning/failed 结果,不能写成本站确认安全。当前只有一个来源,正式发布前建议补源仓库或其他目录站核验。

来源信息

继续浏览同类 Skills