npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@lark-apaas/action-plugin-core

v0.1.0

Published

Core library for platform action execution system

Downloads

13

Readme

@lark-apaas/action-plugin-core

aPaaS 平台 Action 插件核心开发包。

安装

pnpm add @lark-apaas/action-plugin-core zod@^3.25.76

重要: 请使用 zod v3.25.76 或更高版本。项目统一使用 zod v3,以确保 Schema 定义和类型推导的兼容性。

快速开始

基础插件

import { definePlugin } from '@lark-apaas/action-plugin-core';
import { z } from 'zod';

export default definePlugin([
  {
    name: 'sayHello',
    input: z.object({ name: z.string() }),
    output: z.object({ greeting: z.string() }),
    handler: async (context, input) => {
      return { greeting: `Hello, ${input.name}!` };
    },
  },
]);

流式插件

import { definePlugin, StreamTextOutput, Aggregators } from '@lark-apaas/action-plugin-core';
import { z } from 'zod';

export default definePlugin([
  {
    name: 'chat',
    outputMode: 'stream',
    input: z.object({ message: z.string() }),
    output: StreamTextOutput,
    aggregate: Aggregators.text,
    async *handler(context, input) {
      yield { data: { content: 'Hello, ' } };
      yield { data: { content: input.message } };
      yield { data: { content: '!' } };
    },
  },
]);

核心概念

输出模式

| 模式 | 说明 | handler 返回 | 执行方法 | | -------- | ---------------- | ------------------ | ------------- | | unary | 单次响应(默认) | Promise<T> | run() | | stream | 流式响应 | AsyncIterable<T> | runStream() |

流式聚合

流式 action 可以定义 aggregate 聚合器,用于将多个 chunk 聚合为单个结果:

// 预定义聚合器
aggregate: Aggregators.text; // 文本拼接
aggregate: Aggregators.collect; // 数组收集
aggregate: Aggregators.last; // 取最后一个
aggregate: Aggregators.first; // 取第一个
aggregate: Aggregators.mergeRecords; // 合并记录

// 自定义聚合器
aggregate: (chunks) => ({
  total: chunks.reduce((sum, c) => sum + c.value, 0),
});

使用聚合:

const chunks = [];
for await (const chunk of instance.runStream('chat', context, input)) {
  chunks.push(chunk);
}
const result = instance.aggregate('chat', chunks);

API

definePlugin

function definePlugin<TConfig>(
  actions: ActionDefinition[],
  options?: { config?: ZodSchema<TConfig> },
): Plugin<TConfig>;

ActionDefinition

| 字段 | 类型 | 必填 | 说明 | | ------------ | --------------------- | ---- | ----------- | | name | string | 是 | Action 名称 | | input | ZodSchema | 是 | 输入 Schema | | output | ZodSchema | 否 | 输出 Schema | | outputMode | 'unary' \| 'stream' | 否 | 输出模式 | | aggregate | StreamAggregator | 否 | 流式聚合器 | | handler | Function | 是 | 处理函数 |

PluginInstance

interface PluginInstance {
  // Unary
  run(actionName, context, input): Promise<unknown>;

  // Stream
  runStream(actionName, context, input): AsyncIterable<unknown>;
  isStreamAction(actionName): boolean;
  getOutputMode(actionName): 'unary' | 'stream' | undefined;
  aggregate<T>(actionName, chunks): T;

  // 通用
  hasAction(actionName): boolean;
  listActions(): string[];
  getInputSchema(actionName): ZodSchema | undefined;
  getOutputSchema(actionName, input): ZodSchema | undefined;
}

流式工具

Stream Helper

import { Stream } from '@lark-apaas/action-plugin-core';

// 创建流
Stream.of(item1, item2, item3);
Stream.from(asyncIterable);
Stream.once(singleItem);
Stream.empty();

// 转换
stream.map(fn);
stream.filter(fn);
stream.take(n);
stream.concat(otherStream);

标准 Schema

import { streamOutput, StreamTextOutput } from '@lark-apaas/action-plugin-core';

// 自定义流式输出 schema
const MyChunkSchema = streamOutput(z.object({ value: z.number() }));
// 等价于: z.object({ data: z.object({ value: z.number() }) })

// 标准文本流 schema
StreamTextOutput; // { data: { content: string } }

Zod 扩展

本库扩展了 zod,提供 .format().defaultValue() 方法,用于在 JSON Schema 中添加元数据。

.format()

设置 JSON Schema 的 format 字段,用于标注字符串格式:

import { z } from 'zod';
import '@lark-apaas/action-plugin-core'; // 导入即启用扩展

const schema = z.object({
  email: z.string().format('email'),
  website: z.string().format('uri'),
  createdAt: z.string().format('date-time'),
});

支持的 format 类型:date-timedatetimedurationemailuriuri-referenceuuidhostnameipv4ipv6regex 及自定义字符串。

.defaultValue()

设置 JSON Schema 的 default 字段,仅作为元数据标注,不影响字段的必填状态:

const schema = z.object({
  name: z.string().defaultValue('张三'), // required,JSON Schema 中有 default
  age: z.number().defaultValue(18), // required,JSON Schema 中有 default
  status: z.string().default('active'), // optional,zod 原生 default
});

与 zod 原生 .default() 的区别:

| 方法 | 字段状态 | 解析行为 | JSON Schema | | ---------------------- | -------- | ---------------- | ---------------- | | .default(value) | 可选 | 缺失时使用默认值 | default: value | | .defaultValue(value) | 必填 | 无特殊处理 | default: value |

错误处理

import { PluginError, PluginErrorCode } from '@lark-apaas/action-plugin-core';

try {
  await instance.run('action', context, input);
} catch (error) {
  if (error instanceof PluginError) {
    switch (error.code) {
      case PluginErrorCode.ACTION_NOT_FOUND:
      case PluginErrorCode.INVALID_INPUT:
      case PluginErrorCode.INVALID_OUTPUT:
      case PluginErrorCode.EXECUTION_ERROR:
    }
  }
}

文档

License

MIT